Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1310196 > unrolled thread

[RFC 00/29] De-stage android's sync framework

Started byGustavo Padovan <gustavo@padovan.org>
First post2016-01-15 16:00 +0100
Last post2016-01-20 19:30 +0100
Articles 20 on this page of 29 — 7 participants

Back to article view | Back to linux.kernel


Contents

  [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:00 +0100
    [RFC 19/29] dma-buf/fence: create fence_default_fill_driver_data() Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:00 +0100
    [RFC 15/29] dma-buf/fence: create fence_default_get_driver_name() Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:00 +0100
    [RFC 29/29] dma-buf/fence: de-stage sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:00 +0100
    [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:00 +0100
      Re: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal  at destroy phase John Harrison <John.C.Harrison@Intel.com> - 2016-01-15 18:50 +0100
        Re: [RFC 26/29] dma-buf/fence: remove pointless  fence_timeline_signal at destroy phase Gustavo Padovan <gustavo.padovan@collabora.co.uk> - 2016-01-15 19:10 +0100
          Re: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal  at destroy phase Greg Hackmann <ghackmann@google.com> - 2016-01-16 00:50 +0100
    [RFC 08/29] staging/android: Remove WARN_ON_ONCE when releasing sync_fence Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
    [RFC 02/29] staging/android: fix checkpatch warning Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
    [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
      Re: [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline Greg Hackmann <ghackmann@google.com> - 2016-01-20 02:00 +0100
    [RFC 13/29] dma-buf/fence: create fence_default_enable_signaling() Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
    [RFC 05/29] staging/android: remove not used sync_timeline ops Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
    [RFC 14/29] dma-buf/fence: create fence_default_release() Gustavo Padovan <gustavo@padovan.org> - 2016-01-15 16:10 +0100
    Re: [RFC 00/29] De-stage android's sync framework Joe Perches <joe@perches.com> - 2016-01-15 20:20 +0100
    Re: [RFC 00/29] De-stage android's sync framework Daniel Vetter <daniel@ffwll.ch> - 2016-01-19 12:10 +0100
      Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-19 16:30 +0100
        Re: [RFC 00/29] De-stage android's sync framework John Harrison <John.C.Harrison@Intel.com> - 2016-01-19 17:20 +0100
          Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-19 19:00 +0100
            Re: [RFC 00/29] De-stage android's sync framework Daniel Vetter <daniel@ffwll.ch> - 2016-01-19 19:10 +0100
              Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-19 19:20 +0100
      Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-19 21:20 +0100
        Re: [RFC 00/29] De-stage android's sync framework Daniel Vetter <daniel@ffwll.ch> - 2016-01-19 21:40 +0100
    Re: [RFC 00/29] De-stage android's sync framework Maarten Lankhorst <maarten.lankhorst@linux.intel.com> - 2016-01-20 11:30 +0100
      Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-20 15:40 +0100
        Re: [RFC 00/29] De-stage android's sync framework Maarten Lankhorst <maarten.lankhorst@linux.intel.com> - 2016-01-20 16:10 +0100
          Re: [RFC 00/29] De-stage android's sync framework Daniel Vetter <daniel@ffwll.ch> - 2016-01-20 17:30 +0100
          Re: [RFC 00/29] De-stage android's sync framework Gustavo Padovan <gustavo@padovan.org> - 2016-01-20 19:30 +0100

Page 1 of 2  [1] 2  Next page →


#1310196 — [RFC 00/29] De-stage android's sync framework

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:00 +0100
Subject[RFC 00/29] De-stage android's sync framework
Message-ID<qRe14-7zo-5@gated-at.bofh.it>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

This patch series de-stage the sync framework, and in order to accomplish that
a bunch of cleanups/improvements on the sync and fence were made.

The sync framework contained some abstractions around struct fence and those
were removed in the de-staging process among other changes:

Userspace visible changes
-------------------------

 * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
 other change.

Kernel API changes
------------------

 * struct sync_timeline is now struct fence_timeline
 * sync_timeline_ops is now fence_timeline_ops and they now carry struct
 fence as parameter instead of struct sync_pt
 * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
 the fence_timeline is destroyed
 * added fence_add_used_data() to pass a private point to struct fence. This
 pointer is sent back on the .cleanup op.
 * The sync timeline function were moved to be fence_timeline functions:
	 - sync_timeline_create()	-> fence_timeline_create()
	 - sync_timeline_get()		-> fence_timeline_get()
	 - sync_timeline_put()		-> fence_timeline_put()
	 - sync_timeline_destroy()	-> fence_timeline_destroy()
	 - sync_timeline_signal()	-> fence_timeline_signal()

  * sync_pt_create() was replaced be fence_create_on_timeline()

Internal changes
----------------

 * fence_timeline_ops was removed in favor of direct use fence_ops
 * fence default functions were created for fence_ops
 * removed structs sync_pt, sw_sync_timeline and sw_sync_pt

Gustavo Padovan (29):
  staging/android: fix sync framework documentation
  staging/android: fix checkpatch warning
  staging/android: rename sync_fence_release
  staging/android: rename 'android_fence' to 'sync_fence'
  staging/android: remove not used sync_timeline ops
  staging/android: create a 'sync' dir for debugfs information
  staging/android: move sw_sync file to debugfs file
  staging/android: Remove WARN_ON_ONCE when releasing sync_fence
  staging/android: rename struct sync_fence's variables to 'sync_fence'
  staging/android: rename 'sync_pt' to 'fence' in struct sync_fence_cb
  dma-buf/fence: move sync_timeline to fence_timeline
  staging/android: remove struct sync_pt
  dma-buf/fence: create fence_default_enable_signaling()
  dma-buf/fence: create fence_default_release()
  dma-buf/fence: create fence_default_get_driver_name()
  dma-buf/fence: create fence_default_timeline_name()
  dma-buf/fence: store last signaled value on fence timeline
  dma-buf/fence: create default .fence_value_str() and
    .timeline_value_str()
  dma-buf/fence: create fence_default_fill_driver_data()
  dma-buf/fence: remove fence_timeline_ops
  dma-buf/fence: add fence_create_on_timeline()
  staging/android: remove sync_pt_create()
  staging/android: remove sw_sync_timeline and sw_sync_pt
  dma-buf/fence: add debug to fence timeline
  dma-buf/fence: remove unused var from fence_timeline_signal()
  dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
  dma-buf/fence: add .cleanup() callback
  staging/android: use .cleanup() to interrupt any sync_fence waiter
  dma-buf/fence: de-stage sync framework

 drivers/Kconfig                                    |   2 +
 drivers/dma-buf/Kconfig                            |  22 +
 drivers/dma-buf/Makefile                           |   4 +-
 drivers/dma-buf/fence.c                            | 333 ++++++++++
 drivers/dma-buf/fence_debug.c                      | 128 ++++
 drivers/dma-buf/sw_sync.c                          |  65 ++
 drivers/dma-buf/sync.c                             | 527 +++++++++++++++
 drivers/dma-buf/sync_debug.c                       | 279 ++++++++
 drivers/staging/android/Kconfig                    |  28 -
 drivers/staging/android/Makefile                   |   2 -
 drivers/staging/android/sw_sync.c                  | 260 --------
 drivers/staging/android/sync.c                     | 732 ---------------------
 drivers/staging/android/sync.h                     | 366 -----------
 drivers/staging/android/sync_debug.c               | 256 -------
 include/linux/fence.h                              |  77 +++
 .../staging/android => include/linux}/sw_sync.h    |  30 +-
 include/linux/sync.h                               | 201 ++++++
 include/trace/events/fence.h                       |  18 +
 .../android/trace => include/trace/events}/sync.h  |  41 +-
 .../android/uapi => include/uapi/linux}/sw_sync.h  |   0
 .../android/uapi => include/uapi/linux}/sync.h     |   0
 21 files changed, 1672 insertions(+), 1699 deletions(-)
 create mode 100644 drivers/dma-buf/Kconfig
 create mode 100644 drivers/dma-buf/fence_debug.c
 create mode 100644 drivers/dma-buf/sw_sync.c
 create mode 100644 drivers/dma-buf/sync.c
 create mode 100644 drivers/dma-buf/sync_debug.c
 delete mode 100644 drivers/staging/android/sw_sync.c
 delete mode 100644 drivers/staging/android/sync.c
 delete mode 100644 drivers/staging/android/sync.h
 delete mode 100644 drivers/staging/android/sync_debug.c
 rename {drivers/staging/android => include/linux}/sw_sync.h (55%)
 create mode 100644 include/linux/sync.h
 rename {drivers/staging/android/trace => include/trace/events}/sync.h (53%)
 rename {drivers/staging/android/uapi => include/uapi/linux}/sw_sync.h (100%)
 rename {drivers/staging/android/uapi => include/uapi/linux}/sync.h (100%)

-- 
2.5.0

[toc] | [next] | [standalone]


#1310197 — [RFC 19/29] dma-buf/fence: create fence_default_fill_driver_data()

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:00 +0100
Subject[RFC 19/29] dma-buf/fence: create fence_default_fill_driver_data()
Message-ID<qRe16-7zo-63@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

The value needed by sw_sync is now inside struct fence so we create a
default ops to reply that value for us.
---
 drivers/dma-buf/fence.c        | 21 +++++++++++++++++++++
 drivers/staging/android/sync.c | 12 +-----------
 include/linux/fence.h          |  1 +
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 9fdeae8..d9089a0 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -621,6 +621,27 @@ void fence_default_release(struct fence *fence)
 EXPORT_SYMBOL(fence_default_release);
 
 /**
+ * fence_default_fill_driver_data - fence default .fill_driver_data ops
+ * @fence:	[in]	the fence to get the data from
+ * @data:	[out]	the data pointer to write the data
+ * @size:	[in]	the size of the allocated data
+ *
+ * This function return a driver data. In the case the fence seqno value.
+ * It is used at least by the sw_sync to send fence information to the
+ * userspace.
+ */
+int fence_default_fill_driver_data(struct fence *fence, void *data, int size)
+{
+	if (size < sizeof(fence->seqno))
+		return -ENOMEM;
+
+	memcpy(data, &fence->seqno, sizeof(fence->seqno));
+
+	return sizeof(fence->seqno);
+}
+EXPORT_SYMBOL(fence_default_fill_driver_data);
+
+/**
  * fence_default_value_str - default .fence_value_str fence ops
  * @fence:	[in]	the fence to get the value from
  * @str:	[out]	the string pointer to write the value
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 147a494..a275108 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -321,16 +321,6 @@ int sync_fence_wait(struct sync_fence *sync_fence, long timeout)
 }
 EXPORT_SYMBOL(sync_fence_wait);
 
-static int sync_fence_fill_driver_data(struct fence *fence,
-					  void *data, int size)
-{
-	struct fence_timeline *parent = fence_parent(fence);
-
-	if (!parent->ops->fill_driver_data)
-		return 0;
-	return parent->ops->fill_driver_data(fence, data, size);
-}
-
 static const struct fence_ops sync_fence_ops = {
 	.get_driver_name = fence_default_get_driver_name,
 	.get_timeline_name = fence_default_get_timeline_name,
@@ -338,7 +328,7 @@ static const struct fence_ops sync_fence_ops = {
 	.signaled = fence_default_signaled,
 	.wait = fence_default_wait,
 	.release = fence_default_release,
-	.fill_driver_data = sync_fence_fill_driver_data,
+	.fill_driver_data = fence_default_fill_driver_data,
 	.fence_value_str = fence_default_value_str,
 	.timeline_value_str = fence_default_timeline_value_str,
 };
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 5371beb..04438c3 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -285,6 +285,7 @@ bool fence_default_signaled(struct fence *fence);
 bool fence_default_enable_signaling(struct fence *fence);
 signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
 void fence_default_release(struct fence *fence);
+int fence_default_fill_driver_data(struct fence *fence, void *data, int size);
 void fence_default_value_str(struct fence *fence, char *str, int size);
 void fence_default_timeline_value_str(struct fence *fence, char *str, int size);
 int fence_add_callback(struct fence *fence, struct fence_cb *cb,
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310198 — [RFC 15/29] dma-buf/fence: create fence_default_get_driver_name()

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:00 +0100
Subject[RFC 15/29] dma-buf/fence: create fence_default_get_driver_name()
Message-ID<qRe16-7zo-65@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Move driver name handling to fence and create a default function for it.
Returns the driver which the fence belongs.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/dma-buf/fence.c              | 19 ++++++++++++++++++-
 drivers/staging/android/sw_sync.c    |  3 +--
 drivers/staging/android/sync.c       |  9 +--------
 drivers/staging/android/sync_debug.c |  2 +-
 include/linux/fence.h                |  8 ++++----
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index e17397d..85b5074 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -56,6 +56,7 @@ EXPORT_SYMBOL(fence_context_alloc);
  * @num:	[in]	amount of contexts to allocate
  * @ops:	[in]	timeline ops of the caller
  * @size:	[in]	size to allocate struct fence_timeline
+ * @drv_name:	[in]	name of the driver
  * @name:	[in]	name of the timeline
  *
  * This function will return the new fence_timeline or NULL in case of error.
@@ -64,7 +65,8 @@ EXPORT_SYMBOL(fence_context_alloc);
  */
 struct fence_timeline *fence_timeline_create(unsigned num,
 					     struct fence_timeline_ops *ops,
-					     int size, const char *name)
+					     int size, const char *drv_name,
+					     const char *name)
 {
 	struct fence_timeline *timeline;
 
@@ -79,6 +81,7 @@ struct fence_timeline *fence_timeline_create(unsigned num,
 	timeline->ops = ops;
 	timeline->context = fence_context_alloc(1);
 	strlcpy(timeline->name, name, sizeof(timeline->name));
+	strlcpy(timeline->drv_name, drv_name, sizeof(timeline->drv_name));
 
 	INIT_LIST_HEAD(&timeline->child_list_head);
 	INIT_LIST_HEAD(&timeline->active_list_head);
@@ -439,6 +442,20 @@ fence_remove_callback(struct fence *fence, struct fence_cb *cb)
 EXPORT_SYMBOL(fence_remove_callback);
 
 /**
+ * fence_default_get_driver_name - default .get_driver_name op
+ * @fence:	[in]	the fence to get driver name
+ *
+ * This function returns the name of the driver that the fence belongs.
+ */
+const char *fence_default_get_driver_name(struct fence *fence)
+{
+	struct fence_timeline *parent = fence_parent(fence);
+
+	return parent->drv_name;
+}
+EXPORT_SYMBOL(fence_default_get_driver_name);
+
+/**
  * fence_default_enable_signaling - default op for .enable_signaling
  * @fence:	[in]	the fence to enable signaling
  *
diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c
index 9d6a5bd..9720267 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -77,7 +77,6 @@ static void sw_sync_fence_value_str(struct fence *fence,
 }
 
 static struct fence_timeline_ops sw_sync_timeline_ops = {
-	.driver_name = "sw_sync",
 	.has_signaled = sw_sync_fence_has_signaled,
 	.fill_driver_data = sw_sync_fill_driver_data,
 	.timeline_value_str = sw_sync_timeline_value_str,
@@ -89,7 +88,7 @@ struct sw_sync_timeline *sw_sync_timeline_create(const char *name)
 	struct sw_sync_timeline *obj = (struct sw_sync_timeline *)
 		fence_timeline_create(1, &sw_sync_timeline_ops,
 				     sizeof(struct sw_sync_timeline),
-				     name);
+				     "sw_sync", name);
 
 	return obj;
 }
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 6cddec9..c3386a6 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -321,13 +321,6 @@ int sync_fence_wait(struct sync_fence *sync_fence, long timeout)
 }
 EXPORT_SYMBOL(sync_fence_wait);
 
-static const char *sync_fence_get_driver_name(struct fence *fence)
-{
-	struct fence_timeline *parent = fence_parent(fence);
-
-	return parent->ops->driver_name;
-}
-
 static const char *sync_fence_get_timeline_name(struct fence *fence)
 {
 	struct fence_timeline *parent = fence_parent(fence);
@@ -383,7 +376,7 @@ static void sync_fence_timeline_value_str(struct fence *fence,
 }
 
 static const struct fence_ops sync_fence_ops = {
-	.get_driver_name = sync_fence_get_driver_name,
+	.get_driver_name = fence_default_get_driver_name,
 	.get_timeline_name = sync_fence_get_timeline_name,
 	.enable_signaling = fence_default_enable_signaling,
 	.signaled = sync_fence_signaled,
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
index b8602d2..db618ca 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/staging/android/sync_debug.c
@@ -133,7 +133,7 @@ static void sync_print_obj(struct seq_file *s, struct fence_timeline *obj)
 	struct list_head *pos;
 	unsigned long flags;
 
-	seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
+	seq_printf(s, "%s %s", obj->name, obj->drv_name);
 
 	if (obj->ops->timeline_value_str) {
 		char value[64];
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 0c97014..f355c28a 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -36,7 +36,6 @@ struct fence_ops;
 struct fence_cb;
 /**
  * struct fence_timeline_ops - fence context implementation ops
- * @driver_name:	name of the implementation
  * @has_signaled:	returns:
  *			  1 if pt has signaled
  *			  0 if pt has not signaled
@@ -49,8 +48,6 @@ struct fence_cb;
  * @pt_value_str:	fill str with the value of the sync_pt
  */
 struct fence_timeline_ops {
-	const char *driver_name;
-
 	/* required */
 	int (*has_signaled)(struct fence *fence);
 
@@ -80,6 +77,7 @@ struct fence_timeline_ops {
 struct fence_timeline {
 	struct kref		kref;
 	char			name[32];
+	char			drv_name[32];
 	const struct fence_timeline_ops *ops;
 	bool			destroyed;
 	int			value;
@@ -94,7 +92,8 @@ struct fence_timeline {
 
 struct fence_timeline *fence_timeline_create(unsigned num,
 					     struct fence_timeline_ops *ops,
-					     int size, const char *name);
+					     int size, const char *drv_name,
+					     const char *name);
 void fence_timeline_get(struct fence_timeline *timeline);
 void fence_timeline_put(struct fence_timeline *timeline);
 void fence_timeline_destroy(struct fence_timeline *timeline);
@@ -295,6 +294,7 @@ static inline void fence_put(struct fence *fence)
 
 int fence_signal(struct fence *fence);
 int fence_signal_locked(struct fence *fence);
+const char *fence_default_get_driver_name(struct fence *fence);
 bool fence_default_enable_signaling(struct fence *fence);
 signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
 void fence_default_release(struct fence *fence);
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310199 — [RFC 29/29] dma-buf/fence: de-stage sync framework

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:00 +0100
Subject[RFC 29/29] dma-buf/fence: de-stage sync framework
Message-ID<qRe16-7zo-67@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

The sync framework is ready for mainline inclusion. Here we move it to
drivers/dma-buf and the header files to the appropiated places.

The sync framework contained some abstractions around struct fence and those
were removed in the de-staging process among other changes:

Userspace visible changes
-------------------------

 * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
  other change.

Kernel API changes
------------------

 * struct sync_timeline is now struct fence_timeline
 * sync_timeline_ops is now fence_timeline_ops and they now carry struct
 fence as parameter instead of struct sync_pt
 * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
 the fence_timeline is destroyed
 * added fence_add_used_data() to pass a private point to struct fence.
 This pointer is sent back on the .cleanup op.
 * The sync timeline function were moved to be fence_timeline functions:
         - sync_timeline_create()       -> fence_timeline_create()
         - sync_timeline_get()          -> fence_timeline_get()
         - sync_timeline_put()          -> fence_timeline_put()
         - sync_timeline_destroy()      -> fence_timeline_destroy()
         - sync_timeline_signal()       -> fence_timeline_signal()

  * sync_pt_create() was replaced be fence_create_on_timeline()

Internal changes
----------------

 * fence_timeline_ops was removed in favor of direct use fence_ops
 * fence default functions were created for fence_ops
 * removed structs sync_pt, sw_sync_timeline and sw_sync_pt

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/Kconfig                                    |  2 ++
 drivers/dma-buf/Kconfig                            | 22 ++++++++++++++++++++++
 drivers/dma-buf/Makefile                           |  2 ++
 drivers/{staging/android => dma-buf}/sw_sync.c     |  3 +--
 drivers/{staging/android => dma-buf}/sync.c        |  7 ++++---
 drivers/{staging/android => dma-buf}/sync_debug.c  |  2 +-
 drivers/staging/android/Kconfig                    | 19 -------------------
 drivers/staging/android/Makefile                   |  2 --
 .../staging/android => include/linux}/sw_sync.h    |  4 ++--
 {drivers/staging/android => include/linux}/sync.h  |  4 ++--
 .../android/trace => include/trace/events}/sync.h  |  5 ++---
 .../android/uapi => include/uapi/linux}/sw_sync.h  |  0
 .../android/uapi => include/uapi/linux}/sync.h     |  0
 13 files changed, 38 insertions(+), 34 deletions(-)
 create mode 100644 drivers/dma-buf/Kconfig
 rename drivers/{staging/android => dma-buf}/sw_sync.c (98%)
 rename drivers/{staging/android => dma-buf}/sync.c (99%)
 rename drivers/{staging/android => dma-buf}/sync_debug.c (99%)
 rename {drivers/staging/android => include/linux}/sw_sync.h (95%)
 rename {drivers/staging/android => include/linux}/sync.h (99%)
 rename {drivers/staging/android/trace => include/trace/events}/sync.h (92%)
 rename {drivers/staging/android/uapi => include/uapi/linux}/sw_sync.h (100%)
 rename {drivers/staging/android/uapi => include/uapi/linux}/sync.h (100%)

diff --git a/drivers/Kconfig b/drivers/Kconfig
index d2ac339..430f761 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -114,6 +114,8 @@ source "drivers/rtc/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/dma-buf/Kconfig"
+
 source "drivers/dca/Kconfig"
 
 source "drivers/auxdisplay/Kconfig"
diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
new file mode 100644
index 0000000..4168f89
--- /dev/null
+++ b/drivers/dma-buf/Kconfig
@@ -0,0 +1,22 @@
+menu "DMABUF options"
+
+config SYNC
+	bool "Synchronization framework"
+	default n
+	select ANON_INODES
+	select DMA_SHARED_BUFFER
+	---help---
+	  This option enables the framework for synchronization between multiple
+	  drivers.  Sync implementations can take advantage of hardware
+	  synchronization built into devices like GPUs.
+
+config SW_SYNC
+	bool "Software synchronization objects"
+	default n
+	depends on SYNC
+	---help---
+	  A sync object driver that uses a 32bit counter to coordinate
+	  synchronization.  Useful when there is no hardware primitive backing
+	  the synchronization.
+
+endmenu
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index fb03696..b870923 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1 +1,3 @@
 obj-y := dma-buf.o fence.o fence_debug.o reservation.o seqno-fence.o
+obj-$(CONFIG_SYNC)			+= sync.o sync_debug.o
+obj-$(CONFIG_SW_SYNC)			+= sw_sync.o
diff --git a/drivers/staging/android/sw_sync.c b/drivers/dma-buf/sw_sync.c
similarity index 98%
rename from drivers/staging/android/sw_sync.c
rename to drivers/dma-buf/sw_sync.c
index 8c83bad..32d0800 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -22,8 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
-
-#include "sw_sync.h"
+#include <linux/sw_sync.h>
 
 static void sw_sync_cleanup(struct fence *fence, void *user_data)
 {
diff --git a/drivers/staging/android/sync.c b/drivers/dma-buf/sync.c
similarity index 99%
rename from drivers/staging/android/sync.c
rename to drivers/dma-buf/sync.c
index aafecf4..248aa44 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/dma-buf/sync.c
@@ -26,10 +26,10 @@
 #include <linux/uaccess.h>
 #include <linux/anon_inodes.h>
 
-#include "sync.h"
+#include <linux/sync.h>
 
 #define CREATE_TRACE_POINTS
-#include "trace/sync.h"
+#include <trace/events/sync.h>
 
 static const struct file_operations sync_fence_fops;
 
@@ -280,7 +280,7 @@ int sync_fence_wait(struct sync_fence *sync_fence, long timeout)
 
 	trace_sync_wait(sync_fence, 1);
 	for (i = 0; i < sync_fence->num_fences; ++i)
-		trace_fence(sync_fence->cbs[i].fence);
+		trace_sync_fence(sync_fence->cbs[i].fence);
 	ret = wait_event_interruptible_timeout(sync_fence->wq,
 					       atomic_read(&sync_fence->status) <= 0,
 					       timeout);
@@ -395,6 +395,7 @@ static long sync_fence_ioctl_merge(struct sync_fence *sync_fence,
 
 	sync_fence_install(fence3, fd);
 	sync_fence_put(fence2);
+
 	return 0;
 
 err_put_fence3:
diff --git a/drivers/staging/android/sync_debug.c b/drivers/dma-buf/sync_debug.c
similarity index 99%
rename from drivers/staging/android/sync_debug.c
rename to drivers/dma-buf/sync_debug.c
index 8e2ca57..294786b 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -27,7 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/anon_inodes.h>
 #include <linux/time64.h>
-#include "sw_sync.h"
+#include <linux/sw_sync.h>
 
 #ifdef CONFIG_DEBUG_FS
 
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index bd90d20..4b18fee 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -38,25 +38,6 @@ config ANDROID_LOW_MEMORY_KILLER
 	  scripts (/init.rc), and it defines priority values with minimum free memory size
 	  for each priority.
 
-config SYNC
-	bool "Synchronization framework"
-	default n
-	select ANON_INODES
-	select DMA_SHARED_BUFFER
-	---help---
-	  This option enables the framework for synchronization between multiple
-	  drivers.  Sync implementations can take advantage of hardware
-	  synchronization built into devices like GPUs.
-
-config SW_SYNC
-	bool "Software synchronization objects"
-	default n
-	depends on SYNC
-	---help---
-	  A sync object driver that uses a 32bit counter to coordinate
-	  synchronization.  Useful when there is no hardware primitive backing
-	  the synchronization.
-
 source "drivers/staging/android/ion/Kconfig"
 
 endif # if ANDROID
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index c7b6c99..355ad0e 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -6,5 +6,3 @@ obj-$(CONFIG_ASHMEM)			+= ashmem.o
 obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
-obj-$(CONFIG_SYNC)			+= sync.o sync_debug.o
-obj-$(CONFIG_SW_SYNC)			+= sw_sync.o
diff --git a/drivers/staging/android/sw_sync.h b/include/linux/sw_sync.h
similarity index 95%
rename from drivers/staging/android/sw_sync.h
rename to include/linux/sw_sync.h
index f912888..68cb3d9 100644
--- a/drivers/staging/android/sw_sync.h
+++ b/include/linux/sw_sync.h
@@ -19,8 +19,8 @@
 
 #include <linux/types.h>
 #include <linux/kconfig.h>
-#include "sync.h"
-#include "uapi/sw_sync.h"
+#include <linux/sync.h>
+#include <uapi/linux/sw_sync.h>
 
 #if IS_ENABLED(CONFIG_SW_SYNC)
 struct fence_timeline *sw_sync_timeline_create(const char *name);
diff --git a/drivers/staging/android/sync.h b/include/linux/sync.h
similarity index 99%
rename from drivers/staging/android/sync.h
rename to include/linux/sync.h
index d60d9c2..ecefed5 100644
--- a/drivers/staging/android/sync.h
+++ b/include/linux/sync.h
@@ -20,8 +20,8 @@
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/fence.h>
-
-#include "uapi/sync.h"
+#include <linux/sync.h>
+#include <uapi/linux/sync.h>
 
 struct sync_fence;
 
diff --git a/drivers/staging/android/trace/sync.h b/include/trace/events/sync.h
similarity index 92%
rename from drivers/staging/android/trace/sync.h
rename to include/trace/events/sync.h
index 4f68515..fa19962 100644
--- a/drivers/staging/android/trace/sync.h
+++ b/include/trace/events/sync.h
@@ -1,11 +1,10 @@
 #undef TRACE_SYSTEM
-#define TRACE_INCLUDE_PATH ../../drivers/staging/android/trace
 #define TRACE_SYSTEM sync
 
 #if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_SYNC_H
 
-#include "../sync.h"
+#include <linux/sync.h>
 #include <linux/tracepoint.h>
 
 TRACE_EVENT(sync_wait,
@@ -29,7 +28,7 @@ TRACE_EVENT(sync_wait,
 			__get_str(name), __entry->status)
 );
 
-TRACE_EVENT(fence,
+TRACE_EVENT(sync_fence,
 	TP_PROTO(struct fence *fence),
 
 	TP_ARGS(fence),
diff --git a/drivers/staging/android/uapi/sw_sync.h b/include/uapi/linux/sw_sync.h
similarity index 100%
rename from drivers/staging/android/uapi/sw_sync.h
rename to include/uapi/linux/sw_sync.h
diff --git a/drivers/staging/android/uapi/sync.h b/include/uapi/linux/sync.h
similarity index 100%
rename from drivers/staging/android/uapi/sync.h
rename to include/uapi/linux/sync.h
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310200 — [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:00 +0100
Subject[RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
Message-ID<qRe16-7zo-69@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

All changes to timeline value come through the user via
fence_timeline_signal() calls. When fence_timeline_destroy() is called no
changes on timeline->value happens hence call fence_timeline_signal() with
no increment is pointless.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/dma-buf/fence.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 7a5fc9b..26f5f0f 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -136,7 +136,7 @@ EXPORT_SYMBOL(fence_timeline_put);
  * fence_timeline_destroy - destroy a fence_timeline
  * @timeline	[in]	the fence_timeline to destroy
  *
- * This function destroys a timeline. It signals any active fence first.
+ * This function destroys a timeline.
  */
 void fence_timeline_destroy(struct fence_timeline *timeline)
 {
@@ -147,10 +147,6 @@ void fence_timeline_destroy(struct fence_timeline *timeline)
 	 */
 	smp_wmb();
 
-	/*
-	 * signal any children that their parent is going away.
-	 */
-	fence_timeline_signal(timeline, 0);
 	fence_timeline_put(timeline);
 }
 EXPORT_SYMBOL(fence_timeline_destroy);
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310319 — Re: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase

FromJohn Harrison <John.C.Harrison@Intel.com>
Date2016-01-15 18:50 +0100
SubjectRe: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
Message-ID<qRgFB-W7-27@gated-at.bofh.it>
In reply to#1310200
On 15/01/2016 14:55, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> All changes to timeline value come through the user via
> fence_timeline_signal() calls. When fence_timeline_destroy() is called no
> changes on timeline->value happens hence call fence_timeline_signal() with
> no increment is pointless.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>   drivers/dma-buf/fence.c | 6 +-----
>   1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
> index 7a5fc9b..26f5f0f 100644
> --- a/drivers/dma-buf/fence.c
> +++ b/drivers/dma-buf/fence.c
> @@ -136,7 +136,7 @@ EXPORT_SYMBOL(fence_timeline_put);
>    * fence_timeline_destroy - destroy a fence_timeline
>    * @timeline	[in]	the fence_timeline to destroy
>    *
> - * This function destroys a timeline. It signals any active fence first.
> + * This function destroys a timeline.

The implementation for this was certainly broken but I would say it 
should be fixed to match the comment rather than just abandoned 
completely. That is, what happens if a timeline owner destroys their 
timeline while there are outstanding fences which other drivers are 
waiting on? That is presumably a bug in the code that called destroy 
prematurely, but bugs happen.

The old implementation simply leaked the fences. Doing a debugfs dump 
would show the timeline with all its outstanding fences still floating 
around forever after. Worse, anything waiting on them would never be 
signalled and is therefore potentially deadlocked.

Note that I haven't had chance to look through the entire patch series 
yet so maybe this has been fixed up elsewhere. If not, then I think it 
definitely needs looking into.


>    */
>   void fence_timeline_destroy(struct fence_timeline *timeline)
>   {
> @@ -147,10 +147,6 @@ void fence_timeline_destroy(struct fence_timeline *timeline)
>   	 */
>   	smp_wmb();
>   
> -	/*
> -	 * signal any children that their parent is going away.
> -	 */
> -	fence_timeline_signal(timeline, 0);
>   	fence_timeline_put(timeline);
>   }
>   EXPORT_SYMBOL(fence_timeline_destroy);

[toc] | [prev] | [next] | [standalone]


#1310339 — Re: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase

FromGustavo Padovan <gustavo.padovan@collabora.co.uk>
Date2016-01-15 19:10 +0100
SubjectRe: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
Message-ID<qRgYV-1jy-5@gated-at.bofh.it>
In reply to#1310319
2016-01-15 John Harrison <John.C.Harrison@Intel.com>:

> On 15/01/2016 14:55, Gustavo Padovan wrote:
> >From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >
> >All changes to timeline value come through the user via
> >fence_timeline_signal() calls. When fence_timeline_destroy() is called no
> >changes on timeline->value happens hence call fence_timeline_signal() with
> >no increment is pointless.
> >
> >Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >---
> >  drivers/dma-buf/fence.c | 6 +-----
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> >
> >diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
> >index 7a5fc9b..26f5f0f 100644
> >--- a/drivers/dma-buf/fence.c
> >+++ b/drivers/dma-buf/fence.c
> >@@ -136,7 +136,7 @@ EXPORT_SYMBOL(fence_timeline_put);
> >   * fence_timeline_destroy - destroy a fence_timeline
> >   * @timeline	[in]	the fence_timeline to destroy
> >   *
> >- * This function destroys a timeline. It signals any active fence first.
> >+ * This function destroys a timeline.
> 
> The implementation for this was certainly broken but I would say it should
> be fixed to match the comment rather than just abandoned completely. That
> is, what happens if a timeline owner destroys their timeline while there are
> outstanding fences which other drivers are waiting on? That is presumably a
> bug in the code that called destroy prematurely, but bugs happen.
> 
> The old implementation simply leaked the fences. Doing a debugfs dump would
> show the timeline with all its outstanding fences still floating around
> forever after. Worse, anything waiting on them would never be signalled and
> is therefore potentially deadlocked.
> 
> Note that I haven't had chance to look through the entire patch series yet
> so maybe this has been fixed up elsewhere. If not, then I think it
> definitely needs looking into.
> 

Patches 27 and 28 are attempt to fix that. I assumed that if some code is
calling fence_timeline_destroy() it wants to stop everything so I
worked on a solution that stops any waiter and allows the timeline to be
destroyed.

No one is using fence_timeline_destroy() in mainline now, so it is
definately a behaviour we can discuss.

	Gustavo

[toc] | [prev] | [next] | [standalone]


#1310532 — Re: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase

FromGreg Hackmann <ghackmann@google.com>
Date2016-01-16 00:50 +0100
SubjectRe: [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
Message-ID<qRmhY-4D4-17@gated-at.bofh.it>
In reply to#1310339
On 01/15/2016 10:02 AM, Gustavo Padovan wrote:
> Patches 27 and 28 are attempt to fix that. I assumed that if some code is
> calling fence_timeline_destroy() it wants to stop everything so I
> worked on a solution that stops any waiter and allows the timeline to be
> destroyed.
>
> No one is using fence_timeline_destroy() in mainline now, so it is
> definately a behaviour we can discuss.
>
> 	Gustavo
>

+Tom Cherry and Dmitry Torokhov recently discovered that this was broken 
by the refactoring of Android sync on top of dma-buf fences.

Tom and Dmitry, did you send the proposed fix upstream?

[toc] | [prev] | [next] | [standalone]


#1310202 — [RFC 08/29] staging/android: Remove WARN_ON_ONCE when releasing sync_fence

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 08/29] staging/android: Remove WARN_ON_ONCE when releasing sync_fence
Message-ID<qReaK-7SU-19@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

There isn't any problem on removing the sync_pts from the active_list
when the fence is released. If the user decides to close the fence before
it is signaled we should do it and not warn about anything.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/staging/android/sync.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 5028847..273aa4b 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -432,8 +432,9 @@ static void sync_fence_release(struct fence *fence)
 
 	spin_lock_irqsave(fence->lock, flags);
 	list_del(&pt->child_list);
-	if (WARN_ON_ONCE(!list_empty(&pt->active_list)))
+	if (!list_empty(&pt->active_list))
 		list_del(&pt->active_list);
+
 	spin_unlock_irqrestore(fence->lock, flags);
 
 	sync_timeline_put(parent);
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310204 — [RFC 02/29] staging/android: fix checkpatch warning

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 02/29] staging/android: fix checkpatch warning
Message-ID<qReaK-7SU-31@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Trivial indentation fix.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/staging/android/sync.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index 7a4d820..f3d4f75 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -358,6 +358,6 @@ void sync_dump(void);
 # define sync_dump()
 #endif
 int sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode,
-				 int wake_flags, void *key);
+			  int wake_flags, void *key);
 
 #endif /* _LINUX_SYNC_H */
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310205 — [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline
Message-ID<qReaK-7SU-25@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Add the sync timeline from sync framework to fence synchronization system.
This is an attempt to remove some duplication between sync.c and fence.c

The sync_timeline was no more than a wrapper on top of the fence
framework to be used by sw_sync. It simplifies some accesses, for example,
when you have a struct fence you don't need get the sync_pt related to it
to know the parent timeline, it is just a matter of calling
fence_parent() now.

This is just the initial step, the idea is to connect sw_sync direct
with fences removing some abstractions in between.

The sync API changes here are:

 * struct sync_timeline is now struct fence_timeline
 * sync_timeline_ops is now fence_timeline_ops and they now carry struct
 fence as parameter instead of struct sync_pt
 * sync_timeline_create()	-> fence_timeline_create()
 * sync_timeline_get()		-> fence_timeline_get()
 * sync_timeline_put()		-> fence_timeline_put()
 * sync_timeline_destroy()	-> fence_timeline_destroy()
 * sync_timeline_signal()	-> fence_timeline_signal()

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/dma-buf/fence.c              | 125 +++++++++++++++++++++++++++++
 drivers/staging/android/sw_sync.c    |  27 ++++---
 drivers/staging/android/sw_sync.h    |   2 +-
 drivers/staging/android/sync.c       | 150 +++++++----------------------------
 drivers/staging/android/sync.h       | 130 +-----------------------------
 drivers/staging/android/sync_debug.c |  26 +++---
 drivers/staging/android/trace/sync.h |  24 ------
 include/linux/fence.h                |  75 ++++++++++++++++++
 include/trace/events/fence.h         |  24 ++++++
 9 files changed, 285 insertions(+), 298 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 7b05dbe..5dcb94c 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -52,6 +52,131 @@ unsigned fence_context_alloc(unsigned num)
 EXPORT_SYMBOL(fence_context_alloc);
 
 /**
+ * fence_timeline_create - create a new fence_timeline
+ * @num:	[in]	amount of contexts to allocate
+ * @ops:	[in]	timeline ops of the caller
+ * @size:	[in]	size to allocate struct fence_timeline
+ * @name:	[in]	name of the timeline
+ *
+ * This function will return the new fence_timeline or NULL in case of error.
+ * It allocs and initializes a new fence_timeline with a proper fence context
+ * number assigned to it.
+ */
+struct fence_timeline *fence_timeline_create(unsigned num,
+					     struct fence_timeline_ops *ops,
+					     int size, const char *name)
+{
+	struct fence_timeline *timeline;
+
+	if (size < sizeof(*timeline))
+		return NULL;
+
+	timeline = kzalloc(size, GFP_KERNEL);
+	if (!timeline)
+		return NULL;
+
+	kref_init(&timeline->kref);
+	timeline->ops = ops;
+	timeline->context = fence_context_alloc(1);
+	strlcpy(timeline->name, name, sizeof(timeline->name));
+
+	INIT_LIST_HEAD(&timeline->child_list_head);
+	INIT_LIST_HEAD(&timeline->active_list_head);
+	spin_lock_init(&timeline->lock);
+
+	return timeline;
+}
+EXPORT_SYMBOL(fence_timeline_create);
+
+/**
+ * fence_timeline_free - free resources of fence_timeline
+ * @kref	[in]	the kref of the fence_timeline to be freed
+ *
+ * This function frees a fence_timeline which is matter of a simple
+ * call to kfree()
+ */
+static void fence_timeline_free(struct kref *kref)
+{
+	struct fence_timeline *timeline =
+		container_of(kref, struct fence_timeline, kref);
+
+	kfree(timeline);
+}
+
+/**
+ * fence_timeline_get - get a reference to the timeline
+ * @timeline	[in]	the fence_timeline to get a reference
+ *
+ * This function increase the refcnt for the given timeline.
+ */
+void fence_timeline_get(struct fence_timeline *timeline)
+{
+	kref_get(&timeline->kref);
+}
+EXPORT_SYMBOL(fence_timeline_get);
+
+/**
+ * fence_timeline_put - put a reference to the timeline
+ * @timeline	[in]	the fence_timeline to put a reference
+ *
+ * This function decreases the refcnt for the given timeline
+ * and frees it if gets to zero.
+ */
+void fence_timeline_put(struct fence_timeline *timeline)
+{
+	kref_put(&timeline->kref, fence_timeline_free);
+}
+EXPORT_SYMBOL(fence_timeline_put);
+
+/**
+ * fence_timeline_destroy - destroy a fence_timeline
+ * @timeline	[in]	the fence_timeline to destroy
+ *
+ * This function destroys a timeline. It signals any active fence first.
+ */
+void fence_timeline_destroy(struct fence_timeline *timeline)
+{
+	timeline->destroyed = true;
+	/*
+	 * Ensure timeline is marked as destroyed before
+	 * changing timeline's fences status.
+	 */
+	smp_wmb();
+
+	/*
+	 * signal any children that their parent is going away.
+	 */
+	fence_timeline_signal(timeline);
+	fence_timeline_put(timeline);
+}
+EXPORT_SYMBOL(fence_timeline_destroy);
+
+/**
+ * fence_timeline_signal - signal fences on a fence_timeline
+ * @timeline	[in]	the fence_timeline to signal fences
+ *
+ * This function signal fences on a given timeline and remove
+ * those from the active_list.
+ */
+void fence_timeline_signal(struct fence_timeline *timeline)
+{
+	unsigned long flags;
+	LIST_HEAD(signaled_pts);
+	struct fence *fence, *next;
+
+	spin_lock_irqsave(&timeline->lock, flags);
+
+	list_for_each_entry_safe(fence, next, &timeline->active_list_head,
+				 active_list) {
+		if (fence_is_signaled_locked(fence))
+			list_del_init(&fence->active_list);
+	}
+
+	spin_unlock_irqrestore(&timeline->lock, flags);
+}
+EXPORT_SYMBOL(fence_timeline_signal);
+
+/**
  * fence_signal_locked - signal completion of a fence
  * @fence: the fence to signal
  *
diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c
index f491dbc..98f9a29 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -38,18 +38,19 @@ struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value)
 }
 EXPORT_SYMBOL(sw_sync_pt_create);
 
-static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt)
+static int sw_sync_fence_has_signaled(struct fence *fence)
 {
-	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+	struct sw_sync_pt *pt = (struct sw_sync_pt *)fence;
 	struct sw_sync_timeline *obj =
-		(struct sw_sync_timeline *)sync_pt_parent(sync_pt);
+		(struct sw_sync_timeline *)fence_parent(fence);
 
 	return (pt->value > obj->value) ? 0 : 1;
 }
 
-static int sw_sync_fill_driver_data(struct sync_pt *sync_pt,
+static int sw_sync_fill_driver_data(struct fence *fence,
 				    void *data, int size)
 {
+	struct sync_pt *sync_pt = (struct sync_pt *)fence;
 	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
 
 	if (size < sizeof(pt->value))
@@ -60,34 +61,34 @@ static int sw_sync_fill_driver_data(struct sync_pt *sync_pt,
 	return sizeof(pt->value);
 }
 
-static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline,
+static void sw_sync_timeline_value_str(struct fence_timeline *fence_timeline,
 				       char *str, int size)
 {
 	struct sw_sync_timeline *timeline =
-		(struct sw_sync_timeline *)sync_timeline;
+		(struct sw_sync_timeline *)fence_timeline;
 	snprintf(str, size, "%d", timeline->value);
 }
 
-static void sw_sync_pt_value_str(struct sync_pt *sync_pt,
+static void sw_sync_fence_value_str(struct fence *fence,
 				 char *str, int size)
 {
-	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+	struct sw_sync_pt *pt = (struct sw_sync_pt *)fence;
 
 	snprintf(str, size, "%d", pt->value);
 }
 
-static struct sync_timeline_ops sw_sync_timeline_ops = {
+static struct fence_timeline_ops sw_sync_timeline_ops = {
 	.driver_name = "sw_sync",
-	.has_signaled = sw_sync_pt_has_signaled,
+	.has_signaled = sw_sync_fence_has_signaled,
 	.fill_driver_data = sw_sync_fill_driver_data,
 	.timeline_value_str = sw_sync_timeline_value_str,
-	.pt_value_str = sw_sync_pt_value_str,
+	.fence_value_str = sw_sync_fence_value_str,
 };
 
 struct sw_sync_timeline *sw_sync_timeline_create(const char *name)
 {
 	struct sw_sync_timeline *obj = (struct sw_sync_timeline *)
-		sync_timeline_create(&sw_sync_timeline_ops,
+		fence_timeline_create(1, &sw_sync_timeline_ops,
 				     sizeof(struct sw_sync_timeline),
 				     name);
 
@@ -99,6 +100,6 @@ void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc)
 {
 	obj->value += inc;
 
-	sync_timeline_signal(&obj->obj);
+	fence_timeline_signal(&obj->obj);
 }
 EXPORT_SYMBOL(sw_sync_timeline_inc);
diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h
index c87ae9e..cb62298 100644
--- a/drivers/staging/android/sw_sync.h
+++ b/drivers/staging/android/sw_sync.h
@@ -23,7 +23,7 @@
 #include "uapi/sw_sync.h"
 
 struct sw_sync_timeline {
-	struct	sync_timeline	obj;
+	struct	fence_timeline	obj;
 
 	u32			value;
 };
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index decff9e..b07bc24 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -34,110 +34,26 @@
 static const struct fence_ops sync_fence_ops;
 static const struct file_operations sync_fence_fops;
 
-struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
-					   int size, const char *name)
-{
-	struct sync_timeline *obj;
-
-	if (size < sizeof(struct sync_timeline))
-		return NULL;
-
-	obj = kzalloc(size, GFP_KERNEL);
-	if (!obj)
-		return NULL;
-
-	kref_init(&obj->kref);
-	obj->ops = ops;
-	obj->context = fence_context_alloc(1);
-	strlcpy(obj->name, name, sizeof(obj->name));
-
-	INIT_LIST_HEAD(&obj->child_list_head);
-	INIT_LIST_HEAD(&obj->active_list_head);
-	spin_lock_init(&obj->child_list_lock);
-
-	sync_timeline_debug_add(obj);
-
-	return obj;
-}
-EXPORT_SYMBOL(sync_timeline_create);
-
-static void sync_timeline_free(struct kref *kref)
-{
-	struct sync_timeline *obj =
-		container_of(kref, struct sync_timeline, kref);
-
-	sync_timeline_debug_remove(obj);
-
-	kfree(obj);
-}
-
-static void sync_timeline_get(struct sync_timeline *obj)
-{
-	kref_get(&obj->kref);
-}
-
-static void sync_timeline_put(struct sync_timeline *obj)
-{
-	kref_put(&obj->kref, sync_timeline_free);
-}
-
-void sync_timeline_destroy(struct sync_timeline *obj)
-{
-	obj->destroyed = true;
-	/*
-	 * Ensure timeline is marked as destroyed before
-	 * changing timeline's fences status.
-	 */
-	smp_wmb();
-
-	/*
-	 * signal any children that their parent is going away.
-	 */
-	sync_timeline_signal(obj);
-	sync_timeline_put(obj);
-}
-EXPORT_SYMBOL(sync_timeline_destroy);
-
-void sync_timeline_signal(struct sync_timeline *obj)
-{
-	unsigned long flags;
-	LIST_HEAD(signaled_pts);
-	struct sync_pt *pt, *next;
-
-	trace_sync_timeline(obj);
-
-	spin_lock_irqsave(&obj->child_list_lock, flags);
-
-	list_for_each_entry_safe(pt, next, &obj->active_list_head,
-				 active_list) {
-		if (fence_is_signaled_locked(&pt->base))
-			list_del_init(&pt->active_list);
-	}
-
-	spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-EXPORT_SYMBOL(sync_timeline_signal);
-
-struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size)
+struct fence *sync_pt_create(struct fence_timeline *obj, int size)
 {
 	unsigned long flags;
-	struct sync_pt *pt;
+	struct fence *fence;
 
 	if (size < sizeof(struct sync_pt))
 		return NULL;
 
-	pt = kzalloc(size, GFP_KERNEL);
-	if (!pt)
+	fence = kzalloc(size, GFP_KERNEL);
+	if (!fence)
 		return NULL;
 
-	spin_lock_irqsave(&obj->child_list_lock, flags);
-	sync_timeline_get(obj);
-	fence_init(&pt->base, &sync_fence_ops, &obj->child_list_lock,
+	spin_lock_irqsave(&obj->lock, flags);
+	fence_timeline_get(obj);
+	fence_init(fence, &sync_fence_ops, &obj->lock,
 		   obj->context, ++obj->value);
-	list_add_tail(&pt->child_list, &obj->child_list_head);
-	INIT_LIST_HEAD(&pt->active_list);
-	spin_unlock_irqrestore(&obj->child_list_lock, flags);
-	return pt;
+	list_add_tail(&fence->child_list, &obj->child_list_head);
+	INIT_LIST_HEAD(&fence->active_list);
+	spin_unlock_irqrestore(&obj->lock, flags);
+	return fence;
 }
 EXPORT_SYMBOL(sync_pt_create);
 
@@ -412,44 +328,40 @@ EXPORT_SYMBOL(sync_fence_wait);
 
 static const char *sync_fence_get_driver_name(struct fence *fence)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
 	return parent->ops->driver_name;
 }
 
 static const char *sync_fence_get_timeline_name(struct fence *fence)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
 	return parent->name;
 }
 
 static void sync_fence_release(struct fence *fence)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 	unsigned long flags;
 
 	spin_lock_irqsave(fence->lock, flags);
-	list_del(&pt->child_list);
-	if (!list_empty(&pt->active_list))
-		list_del(&pt->active_list);
+	list_del(&fence->child_list);
+	if (!list_empty(&fence->active_list))
+		list_del(&fence->active_list);
 
 	spin_unlock_irqrestore(fence->lock, flags);
 
-	sync_timeline_put(parent);
-	fence_free(&pt->base);
+	fence_timeline_put(parent);
+	fence_free(fence);
 }
 
 static bool sync_fence_signaled(struct fence *fence)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 	int ret;
 
-	ret = parent->ops->has_signaled(pt);
+	ret = parent->ops->has_signaled(fence);
 	if (ret < 0)
 		fence->status = ret;
 	return ret;
@@ -457,46 +369,42 @@ static bool sync_fence_signaled(struct fence *fence)
 
 static bool sync_fence_enable_signaling(struct fence *fence)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
 	if (sync_fence_signaled(fence))
 		return false;
 
-	list_add_tail(&pt->active_list, &parent->active_list_head);
+	list_add_tail(&fence->active_list, &parent->active_list_head);
 	return true;
 }
 
 static int sync_fence_fill_driver_data(struct fence *fence,
 					  void *data, int size)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
 	if (!parent->ops->fill_driver_data)
 		return 0;
-	return parent->ops->fill_driver_data(pt, data, size);
+	return parent->ops->fill_driver_data(fence, data, size);
 }
 
 static void sync_fence_value_str(struct fence *fence,
 				    char *str, int size)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
-	if (!parent->ops->pt_value_str) {
+	if (!parent->ops->fence_value_str) {
 		if (size)
 			*str = 0;
 		return;
 	}
-	parent->ops->pt_value_str(pt, str, size);
+	parent->ops->fence_value_str(fence, str, size);
 }
 
 static void sync_fence_timeline_value_str(struct fence *fence,
 					     char *str, int size)
 {
-	struct sync_pt *pt = container_of(fence, struct sync_pt, base);
-	struct sync_timeline *parent = sync_pt_parent(pt);
+	struct fence_timeline *parent = fence_parent(fence);
 
 	if (!parent->ops->timeline_value_str) {
 		if (size)
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index 43f72a7..53658cc 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -23,91 +23,12 @@
 
 #include "uapi/sync.h"
 
-struct sync_timeline;
-struct sync_pt;
 struct sync_fence;
 
-/**
- * struct sync_timeline_ops - sync object implementation ops
- * @driver_name:	name of the implementation
- * @has_signaled:	returns:
- *			  1 if pt has signaled
- *			  0 if pt has not signaled
- *			 <0 on error
- * @fill_driver_data:	write implementation specific driver data to data.
- *			  should return an error if there is not enough room
- *			  as specified by size.  This information is returned
- *			  to userspace by SYNC_IOC_FENCE_INFO.
- * @timeline_value_str: fill str with the value of the sync_timeline's counter
- * @pt_value_str:	fill str with the value of the sync_pt
- */
-struct sync_timeline_ops {
-	const char *driver_name;
-
-	/* required */
-	int (*has_signaled)(struct sync_pt *pt);
-
-	/* optional */
-	int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
-
-	/* optional */
-	void (*timeline_value_str)(struct sync_timeline *timeline, char *str,
-				   int size);
-
-	/* optional */
-	void (*pt_value_str)(struct sync_pt *pt, char *str, int size);
-};
-
-/**
- * struct sync_timeline - sync object
- * @kref:		reference count on fence.
- * @ops:		ops that define the implementation of the sync_timeline
- * @name:		name of the sync_timeline. Useful for debugging
- * @destroyed:		set when sync_timeline is destroyed
- * @child_list_head:	list of children sync_pts for this sync_timeline
- * @child_list_lock:	lock protecting @child_list_head, destroyed, and
- *			  sync_pt.status
- * @active_list_head:	list of active (unsignaled/errored) sync_pts
- * @sync_timeline_list:	membership in global sync_timeline_list
- */
-struct sync_timeline {
-	struct kref		kref;
-	const struct sync_timeline_ops	*ops;
-	char			name[32];
-
-	/* protected by child_list_lock */
-	bool			destroyed;
-	int			context, value;
-
-	struct list_head	child_list_head;
-	spinlock_t		child_list_lock;
-
-	struct list_head	active_list_head;
-
-#ifdef CONFIG_DEBUG_FS
-	struct list_head	sync_timeline_list;
-#endif
-};
-
-/**
- * struct sync_pt - sync point
- * @base:		base fence class
- * @child_list:		membership in sync_timeline.child_list_head
- * @active_list:	membership in sync_timeline.active_list_head
- */
 struct sync_pt {
 	struct fence base;
-
-	struct list_head	child_list;
-	struct list_head	active_list;
 };
 
-static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt)
-{
-	return container_of(pt->base.lock, struct sync_timeline,
-			    child_list_lock);
-}
-
 struct sync_fence_cb {
 	struct fence_cb cb;
 	struct fence *fence;
@@ -162,53 +83,10 @@ static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
 }
 
 /*
- * API for sync_timeline implementers
+ * API for fence_timeline implementers
  */
 
-/**
- * sync_timeline_create() - creates a sync object
- * @ops:	specifies the implementation ops for the object
- * @size:	size to allocate for this obj
- * @name:	sync_timeline name
- *
- * Creates a new sync_timeline which will use the implementation specified by
- * @ops.  @size bytes will be allocated allowing for implementation specific
- * data to be kept after the generic sync_timeline struct. Returns the
- * sync_timeline object or NULL in case of error.
- */
-struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
-					   int size, const char *name);
-
-/**
- * sync_timeline_destroy() - destroys a sync object
- * @obj:	sync_timeline to destroy
- *
- * A sync implementation should call this when the @obj is going away
- * (i.e. module unload.)  @obj won't actually be freed until all its children
- * sync_pts are freed.
- */
-void sync_timeline_destroy(struct sync_timeline *obj);
-
-/**
- * sync_timeline_signal() - signal a status change on a sync_timeline
- * @obj:	sync_timeline to signal
- *
- * A sync implementation should call this any time one of it's sync_pts
- * has signaled or has an error condition.
- */
-void sync_timeline_signal(struct sync_timeline *obj);
-
-/**
- * sync_pt_create() - creates a sync pt
- * @parent:	sync_pt's parent sync_timeline
- * @size:	size to allocate for this pt
- *
- * Creates a new sync_pt as a child of @parent.  @size bytes will be
- * allocated allowing for implementation specific data to be kept after
- * the generic sync_timeline struct. Returns the sync_pt object or
- * NULL in case of error.
- */
-struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
+struct fence *sync_pt_create(struct fence_timeline *parent, int size);
 
 /**
  * sync_pt_free() - frees a sync pt
@@ -325,8 +203,8 @@ int sync_fence_wait(struct sync_fence *fence, long timeout);
 
 #ifdef CONFIG_DEBUG_FS
 
-void sync_timeline_debug_add(struct sync_timeline *obj);
-void sync_timeline_debug_remove(struct sync_timeline *obj);
+void sync_timeline_debug_add(struct fence_timeline *obj);
+void sync_timeline_debug_remove(struct fence_timeline *obj);
 void sync_fence_debug_add(struct sync_fence *fence);
 void sync_fence_debug_remove(struct sync_fence *fence);
 void sync_dump(void);
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
index 78e9147..f5fd8c3 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/staging/android/sync_debug.c
@@ -38,21 +38,21 @@ static DEFINE_SPINLOCK(sync_timeline_list_lock);
 static LIST_HEAD(sync_fence_list_head);
 static DEFINE_SPINLOCK(sync_fence_list_lock);
 
-void sync_timeline_debug_add(struct sync_timeline *obj)
+void sync_timeline_debug_add(struct fence_timeline *obj)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&sync_timeline_list_lock, flags);
-	list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head);
+	list_add_tail(&obj->fence_timeline_list, &sync_timeline_list_head);
 	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
 }
 
-void sync_timeline_debug_remove(struct sync_timeline *obj)
+void sync_timeline_debug_remove(struct fence_timeline *obj)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&sync_timeline_list_lock, flags);
-	list_del(&obj->sync_timeline_list);
+	list_del(&obj->fence_timeline_list);
 	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
 }
 
@@ -127,7 +127,7 @@ static void sync_print_pt(struct seq_file *s, struct fence *pt, bool fence)
 	seq_puts(s, "\n");
 }
 
-static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
+static void sync_print_obj(struct seq_file *s, struct fence_timeline *obj)
 {
 	struct list_head *pos;
 	unsigned long flags;
@@ -143,13 +143,13 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
 
 	seq_puts(s, "\n");
 
-	spin_lock_irqsave(&obj->child_list_lock, flags);
+	spin_lock_irqsave(&obj->lock, flags);
 	list_for_each(pos, &obj->child_list_head) {
-		struct sync_pt *pt =
-			container_of(pos, struct sync_pt, child_list);
+		struct sync_pt *pt = (struct sync_pt *)
+			container_of(pos, struct fence, child_list);
 		sync_print_pt(s, &pt->base, false);
 	}
-	spin_unlock_irqrestore(&obj->child_list_lock, flags);
+	spin_unlock_irqrestore(&obj->lock, flags);
 }
 
 static void sync_print_sync_fence(struct seq_file *s,
@@ -189,9 +189,9 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
 
 	spin_lock_irqsave(&sync_timeline_list_lock, flags);
 	list_for_each(pos, &sync_timeline_list_head) {
-		struct sync_timeline *obj =
-			container_of(pos, struct sync_timeline,
-				     sync_timeline_list);
+		struct fence_timeline *obj =
+			container_of(pos, struct fence_timeline,
+				     fence_timeline_list);
 
 		sync_print_obj(s, obj);
 		seq_puts(s, "\n");
@@ -251,7 +251,7 @@ static int sw_sync_debugfs_release(struct inode *inode, struct file *file)
 {
 	struct sw_sync_timeline *obj = file->private_data;
 
-	sync_timeline_destroy(&obj->obj);
+	fence_timeline_destroy(&obj->obj);
 	return 0;
 }
 
diff --git a/drivers/staging/android/trace/sync.h b/drivers/staging/android/trace/sync.h
index 77edb97..59c337f 100644
--- a/drivers/staging/android/trace/sync.h
+++ b/drivers/staging/android/trace/sync.h
@@ -8,30 +8,6 @@
 #include "../sync.h"
 #include <linux/tracepoint.h>
 
-TRACE_EVENT(sync_timeline,
-	TP_PROTO(struct sync_timeline *timeline),
-
-	TP_ARGS(timeline),
-
-	TP_STRUCT__entry(
-			__string(name, timeline->name)
-			__array(char, value, 32)
-	),
-
-	TP_fast_assign(
-			__assign_str(name, timeline->name);
-			if (timeline->ops->timeline_value_str) {
-				timeline->ops->timeline_value_str(timeline,
-							__entry->value,
-							sizeof(__entry->value));
-			} else {
-				__entry->value[0] = '\0';
-			}
-	),
-
-	TP_printk("name=%s value=%s", __get_str(name), __entry->value)
-);
-
 TRACE_EVENT(sync_wait,
 	TP_PROTO(struct sync_fence *fence, int begin),
 
diff --git a/include/linux/fence.h b/include/linux/fence.h
index bb52201..a333bf37 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -30,9 +30,75 @@
 #include <linux/printk.h>
 #include <linux/rcupdate.h>
 
+struct fence_timeline;
 struct fence;
 struct fence_ops;
 struct fence_cb;
+/**
+ * struct fence_timeline_ops - fence context implementation ops
+ * @driver_name:	name of the implementation
+ * @has_signaled:	returns:
+ *			  1 if pt has signaled
+ *			  0 if pt has not signaled
+ *			 <0 on error
+ * @fill_driver_data:	write implementation specific driver data to data.
+ *			  should return an error if there is not enough room
+ *			  as specified by size.  This information is returned
+ *			  to userspace by SYNC_IOC_FENCE_INFO.
+ * @timeline_value_str: fill str with the value of the sync_timeline's counter
+ * @pt_value_str:	fill str with the value of the sync_pt
+ */
+struct fence_timeline_ops {
+	const char *driver_name;
+
+	/* required */
+	int (*has_signaled)(struct fence *fence);
+
+	/* optional */
+	int (*fill_driver_data)(struct fence *fence, void *data, int size);
+
+	/* optional */
+	void (*timeline_value_str)(struct fence_timeline *timeline, char *str,
+				   int size);
+
+	/* optional */
+	void (*fence_value_str)(struct fence *fence, char *str, int size);
+};
+
+/**
+ * struct fence_timeline - timeline for software synchronization primitive
+ * @kref: refcount for timeline lifetime
+ * @name: name of the timeline
+ * @ops: pointer to fence_timeline_ops of users
+ * @detroyed: if true, the destroy process has started
+ * @value: value of the last signaled fence
+ * @child_list_head: list of child fences
+ * @active_list_head: list of active(not signaled) fences
+ * @lock: to protect lists access
+ * @fences: list of all timelines created
+ */
+struct fence_timeline {
+	struct kref		kref;
+	char			name[32];
+	const struct fence_timeline_ops *ops;
+	bool			destroyed;
+	int			value;
+	int			context;
+	struct list_head	child_list_head;
+	struct list_head	active_list_head;
+	spinlock_t		lock;
+#ifdef CONFIG_DEBUG_FS
+	struct list_head        fence_timeline_list;
+#endif
+};
+
+struct fence_timeline *fence_timeline_create(unsigned num,
+					     struct fence_timeline_ops *ops,
+					     int size, const char *name);
+void fence_timeline_get(struct fence_timeline *timeline);
+void fence_timeline_put(struct fence_timeline *timeline);
+void fence_timeline_destroy(struct fence_timeline *timeline);
+void fence_timeline_signal(struct fence_timeline *timeline);
 
 /**
  * struct fence - software synchronization primitive
@@ -79,6 +145,8 @@ struct fence {
 	unsigned long flags;
 	ktime_t timestamp;
 	int status;
+	struct list_head child_list;
+	struct list_head active_list;
 };
 
 enum fence_flag_bits {
@@ -181,6 +249,13 @@ void fence_init(struct fence *fence, const struct fence_ops *ops,
 void fence_release(struct kref *kref);
 void fence_free(struct fence *fence);
 
+
+static inline struct fence_timeline *fence_parent(struct fence *fence)
+{
+	return container_of(fence->lock, struct fence_timeline,
+			    lock);
+}
+
 /**
  * fence_get - increases refcount of the fence
  * @fence:	[in]	fence to increase refcount of
diff --git a/include/trace/events/fence.h b/include/trace/events/fence.h
index 98feb1b..c4d01de 100644
--- a/include/trace/events/fence.h
+++ b/include/trace/events/fence.h
@@ -48,6 +48,30 @@ TRACE_EVENT(fence_annotate_wait_on,
 		  __entry->waiting_context, __entry->waiting_seqno)
 );
 
+TRACE_EVENT(fence_timeline,
+	TP_PROTO(struct fence_timeline *timeline),
+
+	TP_ARGS(timeline),
+
+	TP_STRUCT__entry(
+			__string(name, timeline->name)
+			__array(char, value, 32)
+	),
+
+	TP_fast_assign(
+			__assign_str(name, timeline->name);
+			if (timeline->ops->timeline_value_str) {
+				timeline->ops->timeline_value_str(timeline,
+							__entry->value,
+							sizeof(__entry->value));
+			} else {
+				__entry->value[0] = '\0';
+			}
+	),
+
+	TP_printk("name=%s value=%s", __get_str(name), __entry->value)
+);
+
 DECLARE_EVENT_CLASS(fence,
 
 	TP_PROTO(struct fence *fence),
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1312629 — Re: [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline

FromGreg Hackmann <ghackmann@google.com>
Date2016-01-20 02:00 +0100
SubjectRe: [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline
Message-ID<qSPhX-77l-59@gated-at.bofh.it>
In reply to#1310205
On 01/15/2016 06:55 AM, Gustavo Padovan wrote:
>   /**
> + * fence_timeline_create - create a new fence_timeline
> + * @num:	[in]	amount of contexts to allocate
[...]
> + */
> +struct fence_timeline *fence_timeline_create(unsigned num,
> +					     struct fence_timeline_ops *ops,
> +					     int size, const char *name)
> +{
[...]
> +	timeline->context = fence_context_alloc(1);

fence_context_alloc(num)

[toc] | [prev] | [next] | [standalone]


#1310208 — [RFC 13/29] dma-buf/fence: create fence_default_enable_signaling()

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 13/29] dma-buf/fence: create fence_default_enable_signaling()
Message-ID<qReaL-7SU-51@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Add a default .enable_signaling() op to be used on fence_ops vtable.
fence_default_enable_signaling() checks if the was not signaled yet
and adds it to the active_list.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/dma-buf/fence.c        | 22 ++++++++++++++++++++++
 drivers/staging/android/sync.c | 13 +------------
 include/linux/fence.h          |  1 +
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 5dcb94c..51b77ed 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -438,6 +438,28 @@ fence_remove_callback(struct fence *fence, struct fence_cb *cb)
 }
 EXPORT_SYMBOL(fence_remove_callback);
 
+/**
+ * fence_default_enable_signaling - default op for .enable_signaling
+ * @fence:	[in]	the fence to enable signaling
+ *
+ * This function checks if the fence was already signaled and if not
+ * adds it to the list of active fences.
+ */
+bool fence_default_enable_signaling(struct fence *fence)
+{
+	struct fence_timeline *timeline = fence_parent(fence);
+
+	if (!timeline)
+		return false;
+
+	if (fence->ops->signaled && fence->ops->signaled(fence))
+		return false;
+
+	list_add_tail(&fence->active_list, &timeline->active_list_head);
+	return true;
+}
+EXPORT_SYMBOL(fence_default_enable_signaling);
+
 struct default_wait_cb {
 	struct fence_cb base;
 	struct task_struct *task;
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 417cf9f..87fb93c 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -362,17 +362,6 @@ static bool sync_fence_signaled(struct fence *fence)
 	return ret;
 }
 
-static bool sync_fence_enable_signaling(struct fence *fence)
-{
-	struct fence_timeline *parent = fence_parent(fence);
-
-	if (sync_fence_signaled(fence))
-		return false;
-
-	list_add_tail(&fence->active_list, &parent->active_list_head);
-	return true;
-}
-
 static int sync_fence_fill_driver_data(struct fence *fence,
 					  void *data, int size)
 {
@@ -412,7 +401,7 @@ static void sync_fence_timeline_value_str(struct fence *fence,
 static const struct fence_ops sync_fence_ops = {
 	.get_driver_name = sync_fence_get_driver_name,
 	.get_timeline_name = sync_fence_get_timeline_name,
-	.enable_signaling = sync_fence_enable_signaling,
+	.enable_signaling = fence_default_enable_signaling,
 	.signaled = sync_fence_signaled,
 	.wait = fence_default_wait,
 	.release = sync_fence_release,
diff --git a/include/linux/fence.h b/include/linux/fence.h
index a333bf37..73b8c9f 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -295,6 +295,7 @@ static inline void fence_put(struct fence *fence)
 
 int fence_signal(struct fence *fence);
 int fence_signal_locked(struct fence *fence);
+bool fence_default_enable_signaling(struct fence *fence);
 signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
 int fence_add_callback(struct fence *fence, struct fence_cb *cb,
 		       fence_func_t func);
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310210 — [RFC 05/29] staging/android: remove not used sync_timeline ops

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 05/29] staging/android: remove not used sync_timeline ops
Message-ID<qReaL-7SU-55@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

.dup and .compare are not used by the sync framework, so remove them
from sw_sync.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/staging/android/sw_sync.c | 29 +----------------------------
 drivers/staging/android/sync.c    |  6 ------
 drivers/staging/android/sync.h    | 19 -------------------
 3 files changed, 1 insertion(+), 53 deletions(-)

diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c
index c4ff167..566dcdc 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -25,14 +25,6 @@
 
 #include "sw_sync.h"
 
-static int sw_sync_cmp(u32 a, u32 b)
-{
-	if (a == b)
-		return 0;
-
-	return ((s32)a - (s32)b) < 0 ? -1 : 1;
-}
-
 struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value)
 {
 	struct sw_sync_pt *pt;
@@ -46,30 +38,13 @@ struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value)
 }
 EXPORT_SYMBOL(sw_sync_pt_create);
 
-static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt)
-{
-	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
-	struct sw_sync_timeline *obj =
-		(struct sw_sync_timeline *)sync_pt_parent(sync_pt);
-
-	return (struct sync_pt *)sw_sync_pt_create(obj, pt->value);
-}
-
 static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt)
 {
 	struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
 	struct sw_sync_timeline *obj =
 		(struct sw_sync_timeline *)sync_pt_parent(sync_pt);
 
-	return sw_sync_cmp(obj->value, pt->value) >= 0;
-}
-
-static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
-{
-	struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a;
-	struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b;
-
-	return sw_sync_cmp(pt_a->value, pt_b->value);
+	return (pt->value > obj->value) ? 0 : 1;
 }
 
 static int sw_sync_fill_driver_data(struct sync_pt *sync_pt,
@@ -103,9 +78,7 @@ static void sw_sync_pt_value_str(struct sync_pt *sync_pt,
 
 static struct sync_timeline_ops sw_sync_timeline_ops = {
 	.driver_name = "sw_sync",
-	.dup = sw_sync_pt_dup,
 	.has_signaled = sw_sync_pt_has_signaled,
-	.compare = sw_sync_pt_compare,
 	.fill_driver_data = sw_sync_fill_driver_data,
 	.timeline_value_str = sw_sync_timeline_value_str,
 	.pt_value_str = sw_sync_pt_value_str,
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index fa756ef..5028847 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -68,9 +68,6 @@ static void sync_timeline_free(struct kref *kref)
 
 	sync_timeline_debug_remove(obj);
 
-	if (obj->ops->release_obj)
-		obj->ops->release_obj(obj);
-
 	kfree(obj);
 }
 
@@ -439,9 +436,6 @@ static void sync_fence_release(struct fence *fence)
 		list_del(&pt->active_list);
 	spin_unlock_irqrestore(fence->lock, flags);
 
-	if (parent->ops->free_pt)
-		parent->ops->free_pt(pt);
-
 	sync_timeline_put(parent);
 	fence_free(&pt->base);
 }
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index f3d4f75..ad45659 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -30,17 +30,10 @@ struct sync_fence;
 /**
  * struct sync_timeline_ops - sync object implementation ops
  * @driver_name:	name of the implementation
- * @dup:		duplicate a sync_pt
  * @has_signaled:	returns:
  *			  1 if pt has signaled
  *			  0 if pt has not signaled
  *			 <0 on error
- * @compare:		returns:
- *			  1 if b will signal before a
- *			  0 if a and b will signal at the same time
- *			 -1 if a will signal before b
- * @free_pt:		called before sync_pt is freed
- * @release_obj:	called before sync_timeline is freed
  * @fill_driver_data:	write implementation specific driver data to data.
  *			  should return an error if there is not enough room
  *			  as specified by size.  This information is returned
@@ -52,20 +45,8 @@ struct sync_timeline_ops {
 	const char *driver_name;
 
 	/* required */
-	struct sync_pt * (*dup)(struct sync_pt *pt);
-
-	/* required */
 	int (*has_signaled)(struct sync_pt *pt);
 
-	/* required */
-	int (*compare)(struct sync_pt *a, struct sync_pt *b);
-
-	/* optional */
-	void (*free_pt)(struct sync_pt *sync_pt);
-
-	/* optional */
-	void (*release_obj)(struct sync_timeline *sync_timeline);
-
 	/* optional */
 	int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
 
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310211 — [RFC 14/29] dma-buf/fence: create fence_default_release()

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-15 16:10 +0100
Subject[RFC 14/29] dma-buf/fence: create fence_default_release()
Message-ID<qReaM-7SU-61@gated-at.bofh.it>
In reply to#1310196
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Add a default .release() op to be used on fence_ops vtable.
It removes the fences from any list it was added, removes a timeline ref
and free the fence.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 drivers/dma-buf/fence.c        | 28 ++++++++++++++++++++++++++++
 drivers/staging/android/sync.c | 18 +-----------------
 include/linux/fence.h          |  1 +
 3 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 51b77ed..e17397d 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -544,6 +544,34 @@ out:
 }
 EXPORT_SYMBOL(fence_default_wait);
 
+/**
+ * fence_default_release - default .release op
+ * @fence:	[in]	the fence to release
+ *
+ * This function removes the fence from the child_list * and active_list
+ * (if it was active) and drops its timeline ref. Finally it frees the
+ * fence.
+ */
+void fence_default_release(struct fence *fence)
+{
+	struct fence_timeline *timeline = fence_parent(fence);
+	unsigned long flags;
+
+	if (!timeline)
+		return;
+
+	spin_lock_irqsave(fence->lock, flags);
+	list_del(&fence->child_list);
+	if (!list_empty(&fence->active_list))
+		list_del(&fence->active_list);
+
+	spin_unlock_irqrestore(fence->lock, flags);
+
+	fence_timeline_put(timeline);
+	fence_free(fence);
+}
+EXPORT_SYMBOL(fence_default_release);
+
 static bool
 fence_test_signaled_any(struct fence **fences, uint32_t count)
 {
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 87fb93c..6cddec9 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -335,22 +335,6 @@ static const char *sync_fence_get_timeline_name(struct fence *fence)
 	return parent->name;
 }
 
-static void sync_fence_release(struct fence *fence)
-{
-	struct fence_timeline *parent = fence_parent(fence);
-	unsigned long flags;
-
-	spin_lock_irqsave(fence->lock, flags);
-	list_del(&fence->child_list);
-	if (!list_empty(&fence->active_list))
-		list_del(&fence->active_list);
-
-	spin_unlock_irqrestore(fence->lock, flags);
-
-	fence_timeline_put(parent);
-	fence_free(fence);
-}
-
 static bool sync_fence_signaled(struct fence *fence)
 {
 	struct fence_timeline *parent = fence_parent(fence);
@@ -404,7 +388,7 @@ static const struct fence_ops sync_fence_ops = {
 	.enable_signaling = fence_default_enable_signaling,
 	.signaled = sync_fence_signaled,
 	.wait = fence_default_wait,
-	.release = sync_fence_release,
+	.release = fence_default_release,
 	.fill_driver_data = sync_fence_fill_driver_data,
 	.fence_value_str = sync_fence_value_str,
 	.timeline_value_str = sync_fence_timeline_value_str,
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 73b8c9f..0c97014 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -297,6 +297,7 @@ int fence_signal(struct fence *fence);
 int fence_signal_locked(struct fence *fence);
 bool fence_default_enable_signaling(struct fence *fence);
 signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
+void fence_default_release(struct fence *fence);
 int fence_add_callback(struct fence *fence, struct fence_cb *cb,
 		       fence_func_t func);
 bool fence_remove_callback(struct fence *fence, struct fence_cb *cb);
-- 
2.5.0

[toc] | [prev] | [next] | [standalone]


#1310383

FromJoe Perches <joe@perches.com>
Date2016-01-15 20:20 +0100
Message-ID<qRi4F-204-1@gated-at.bofh.it>
In reply to#1310196
On Fri, 2016-01-15 at 12:55 -0200, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> This patch series de-stage the sync framework, and in order to accomplish that
> a bunch of cleanups/improvements on the sync and fence were made.

Perhaps add/update a MAINTAINERS entry too?

[toc] | [prev] | [next] | [standalone]


#1312122

FromDaniel Vetter <daniel@ffwll.ch>
Date2016-01-19 12:10 +0100
Message-ID<qSCkH-6VX-27@gated-at.bofh.it>
In reply to#1310196
On Fri, Jan 15, 2016 at 12:55:10PM -0200, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> This patch series de-stage the sync framework, and in order to accomplish that
> a bunch of cleanups/improvements on the sync and fence were made.
> 
> The sync framework contained some abstractions around struct fence and those
> were removed in the de-staging process among other changes:
> 
> Userspace visible changes
> -------------------------
> 
>  * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
>  other change.
> 
> Kernel API changes
> ------------------
> 
>  * struct sync_timeline is now struct fence_timeline
>  * sync_timeline_ops is now fence_timeline_ops and they now carry struct
>  fence as parameter instead of struct sync_pt
>  * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
>  the fence_timeline is destroyed
>  * added fence_add_used_data() to pass a private point to struct fence. This
>  pointer is sent back on the .cleanup op.
>  * The sync timeline function were moved to be fence_timeline functions:
> 	 - sync_timeline_create()	-> fence_timeline_create()
> 	 - sync_timeline_get()		-> fence_timeline_get()
> 	 - sync_timeline_put()		-> fence_timeline_put()
> 	 - sync_timeline_destroy()	-> fence_timeline_destroy()
> 	 - sync_timeline_signal()	-> fence_timeline_signal()
> 
>   * sync_pt_create() was replaced be fence_create_on_timeline()
> 
> Internal changes
> ----------------
> 
>  * fence_timeline_ops was removed in favor of direct use fence_ops
>  * fence default functions were created for fence_ops
>  * removed structs sync_pt, sw_sync_timeline and sw_sync_pt

Bunch of fairly random comments all over:

- include/uapi/linux/sw_sync.h imo should be dropped, it's just a private
  debugfs interface between fence fds and the testsuite. Since the plan is
  to have the testcases integrated into the kernel tree too we don't need
  a public header.

- similar for include/linux/sw_sync.h Imo that should all be moved into
  sync_debug.c. Same for sw_sync.c, that should all land in sync_debug
  imo, and made optional with a Kconfig option. At least we should reuse
  CONFIG_DEBUGFS.

- fence_context and fence_timeline are really the same. timeline has some
  super-basic support for doing sw-only fence timelines, but imo that's
  not really worth keeping (and if so better to keep seperate in a
  sw-fence.c or similar, like seqno-fence.c). The other main thing
  timeline provides is support to clean up fences on a timeline. And imo
  that cleanup should be done by the core fence support, not by the add-on
  stuff.

Interlude about fence cleanup on driver unload:

Working drivers imo should never call timeline_destroy when there's still
an unsignalled fence around for that timeline/context. That just means
they're broken and failed to clean up all the pending work. So the problem
really is only what to do with fences where the driver disappeared, and
for that we essentially need a fence_revoke() function (which could be
called internally from timeline_free). So here's what I think
timeline_free should do:

for_each_fence_on_timel() {
	WARN_ON(!fence_is_signalled());

	fence_revoke(fence);
}

Implementing fence_revoke is a bit tricky since we need to make sure the
memory contained ->ops and similar stuff doesn't disappear. Simplest
option might be to grab a temporary reference (using
kref_get_unless_zero), and then exchange ->ops with one that has only a
release function. We don't need anything else as long as all fence_*
functions the kernel might call check for signalling correctly first
(fence_wait is broken at least).

Or we just give up (for now) and declare module unload as slightly racy.
dma-buf is similar. An intermediate option might be to at least add a
THIS_MODULE reference to each fence (but that's a bit expensive ...).

- back to timeline vs. context: I have no idea how to best clean up this
  mess, but least painful option long-term is probably to switch over all
  current users of fence_context_alloc to timelines and remove the plain
  context interface.

- Imo the interface in include/linux/sync.h is duplicating too much of
  fence.h. I think the only bits we need are the refcounting, creating,
  fd-install and that's it. Plus a macro to loop over all the fences in a
  sync_fence. With that drivers will only ever deal with a pile of
  struct fence, making implicit fencing (using the fence list in dma-buf)
  and explicit fencing (using the fence list in sync_fence) much more
  similar.

  And we can easily do that since no internal users ;-)

- get_timeline_name and get_driver_name are imo too much indirection, just
  add ->(drv_)name field to each of these.

- struct sync_fence is a major confusion imo against struct fence. It
  made much more sense in the pure-android world where fence == sync_pt.
  Maybe we can rename sync_fence to sync_fence_fd (a bit long, and fd is a
  bit inaccurate), sync_file (like this best), fence_file (sounds silly
  imo), or something else?

- I guess just not yet part of this rfc, but moving the testsuite and
  adding kerneldoc for this is planned I guess? If you feel like I think
  it'd be best. We pull the current dma-buf stuff into
  device-drivers.tmpl, but it's completely lacking overview docs and all
  that. And I'd like to duplicate at least the dma-buf/fence sections into
  the gpu.tmpl docbook.

- If we make timelines first class objects I think we could move some of
  the fields from struct fence to struct fence_timeline. E.g. the ops
  struct. That also makes it clearer that some of the vfuncs really should
  be taking a struct fence_timeline *timeline instead of a struct fence
  *fence as their primary parameter.

Cheers, Daniel

> 
> Gustavo Padovan (29):
>   staging/android: fix sync framework documentation
>   staging/android: fix checkpatch warning
>   staging/android: rename sync_fence_release
>   staging/android: rename 'android_fence' to 'sync_fence'
>   staging/android: remove not used sync_timeline ops
>   staging/android: create a 'sync' dir for debugfs information
>   staging/android: move sw_sync file to debugfs file
>   staging/android: Remove WARN_ON_ONCE when releasing sync_fence
>   staging/android: rename struct sync_fence's variables to 'sync_fence'
>   staging/android: rename 'sync_pt' to 'fence' in struct sync_fence_cb
>   dma-buf/fence: move sync_timeline to fence_timeline
>   staging/android: remove struct sync_pt
>   dma-buf/fence: create fence_default_enable_signaling()
>   dma-buf/fence: create fence_default_release()
>   dma-buf/fence: create fence_default_get_driver_name()
>   dma-buf/fence: create fence_default_timeline_name()
>   dma-buf/fence: store last signaled value on fence timeline
>   dma-buf/fence: create default .fence_value_str() and
>     .timeline_value_str()
>   dma-buf/fence: create fence_default_fill_driver_data()
>   dma-buf/fence: remove fence_timeline_ops
>   dma-buf/fence: add fence_create_on_timeline()
>   staging/android: remove sync_pt_create()
>   staging/android: remove sw_sync_timeline and sw_sync_pt
>   dma-buf/fence: add debug to fence timeline
>   dma-buf/fence: remove unused var from fence_timeline_signal()
>   dma-buf/fence: remove pointless fence_timeline_signal at destroy phase
>   dma-buf/fence: add .cleanup() callback
>   staging/android: use .cleanup() to interrupt any sync_fence waiter
>   dma-buf/fence: de-stage sync framework
> 
>  drivers/Kconfig                                    |   2 +
>  drivers/dma-buf/Kconfig                            |  22 +
>  drivers/dma-buf/Makefile                           |   4 +-
>  drivers/dma-buf/fence.c                            | 333 ++++++++++
>  drivers/dma-buf/fence_debug.c                      | 128 ++++
>  drivers/dma-buf/sw_sync.c                          |  65 ++
>  drivers/dma-buf/sync.c                             | 527 +++++++++++++++
>  drivers/dma-buf/sync_debug.c                       | 279 ++++++++
>  drivers/staging/android/Kconfig                    |  28 -
>  drivers/staging/android/Makefile                   |   2 -
>  drivers/staging/android/sw_sync.c                  | 260 --------
>  drivers/staging/android/sync.c                     | 732 ---------------------
>  drivers/staging/android/sync.h                     | 366 -----------
>  drivers/staging/android/sync_debug.c               | 256 -------
>  include/linux/fence.h                              |  77 +++
>  .../staging/android => include/linux}/sw_sync.h    |  30 +-
>  include/linux/sync.h                               | 201 ++++++
>  include/trace/events/fence.h                       |  18 +
>  .../android/trace => include/trace/events}/sync.h  |  41 +-
>  .../android/uapi => include/uapi/linux}/sw_sync.h  |   0
>  .../android/uapi => include/uapi/linux}/sync.h     |   0
>  21 files changed, 1672 insertions(+), 1699 deletions(-)
>  create mode 100644 drivers/dma-buf/Kconfig
>  create mode 100644 drivers/dma-buf/fence_debug.c
>  create mode 100644 drivers/dma-buf/sw_sync.c
>  create mode 100644 drivers/dma-buf/sync.c
>  create mode 100644 drivers/dma-buf/sync_debug.c
>  delete mode 100644 drivers/staging/android/sw_sync.c
>  delete mode 100644 drivers/staging/android/sync.c
>  delete mode 100644 drivers/staging/android/sync.h
>  delete mode 100644 drivers/staging/android/sync_debug.c
>  rename {drivers/staging/android => include/linux}/sw_sync.h (55%)
>  create mode 100644 include/linux/sync.h
>  rename {drivers/staging/android/trace => include/trace/events}/sync.h (53%)
>  rename {drivers/staging/android/uapi => include/uapi/linux}/sw_sync.h (100%)
>  rename {drivers/staging/android/uapi => include/uapi/linux}/sync.h (100%)
> 
> -- 
> 2.5.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1312325

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-19 16:30 +0100
Message-ID<qSGoh-1fW-3@gated-at.bofh.it>
In reply to#1312122
Hi Daniel, 

2016-01-19 Daniel Vetter <daniel@ffwll.ch>:

> On Fri, Jan 15, 2016 at 12:55:10PM -0200, Gustavo Padovan wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > This patch series de-stage the sync framework, and in order to accomplish that
> > a bunch of cleanups/improvements on the sync and fence were made.
> > 
> > The sync framework contained some abstractions around struct fence and those
> > were removed in the de-staging process among other changes:
> > 
> > Userspace visible changes
> > -------------------------
> > 
> >  * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
> >  other change.
> > 
> > Kernel API changes
> > ------------------
> > 
> >  * struct sync_timeline is now struct fence_timeline
> >  * sync_timeline_ops is now fence_timeline_ops and they now carry struct
> >  fence as parameter instead of struct sync_pt
> >  * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
> >  the fence_timeline is destroyed
> >  * added fence_add_used_data() to pass a private point to struct fence. This
> >  pointer is sent back on the .cleanup op.
> >  * The sync timeline function were moved to be fence_timeline functions:
> > 	 - sync_timeline_create()	-> fence_timeline_create()
> > 	 - sync_timeline_get()		-> fence_timeline_get()
> > 	 - sync_timeline_put()		-> fence_timeline_put()
> > 	 - sync_timeline_destroy()	-> fence_timeline_destroy()
> > 	 - sync_timeline_signal()	-> fence_timeline_signal()
> > 
> >   * sync_pt_create() was replaced be fence_create_on_timeline()
> > 
> > Internal changes
> > ----------------
> > 
> >  * fence_timeline_ops was removed in favor of direct use fence_ops
> >  * fence default functions were created for fence_ops
> >  * removed structs sync_pt, sw_sync_timeline and sw_sync_pt
> 
> Bunch of fairly random comments all over:
> 
> - include/uapi/linux/sw_sync.h imo should be dropped, it's just a private
>   debugfs interface between fence fds and the testsuite. Since the plan is
>   to have the testcases integrated into the kernel tree too we don't need
>   a public header.
> 
> - similar for include/linux/sw_sync.h Imo that should all be moved into
>   sync_debug.c. Same for sw_sync.c, that should all land in sync_debug
>   imo, and made optional with a Kconfig option. At least we should reuse
>   CONFIG_DEBUGFS.

These two items sounds reasonable to me.

> 
> - fence_context and fence_timeline are really the same. timeline has some
>   super-basic support for doing sw-only fence timelines, but imo that's
>   not really worth keeping (and if so better to keep seperate in a
>   sw-fence.c or similar, like seqno-fence.c). The other main thing
>   timeline provides is support to clean up fences on a timeline. And imo
>   that cleanup should be done by the core fence support, not by the add-on
>   stuff.

Yes, they are. But I currently doesn't know how to merge them best, so I
decided to go for a RFC instead of trying some crazy solution touching
all fence_context users.

> 
> Interlude about fence cleanup on driver unload:
> 
> Working drivers imo should never call timeline_destroy when there's still
> an unsignalled fence around for that timeline/context. That just means
> they're broken and failed to clean up all the pending work. So the problem
> really is only what to do with fences where the driver disappeared, and
> for that we essentially need a fence_revoke() function (which could be
> called internally from timeline_free). So here's what I think
> timeline_free should do:
> 
> for_each_fence_on_timel() {
> 	WARN_ON(!fence_is_signalled());
> 
> 	fence_revoke(fence);
> }
> 
> Implementing fence_revoke is a bit tricky since we need to make sure the
> memory contained ->ops and similar stuff doesn't disappear. Simplest
> option might be to grab a temporary reference (using
> kref_get_unless_zero), and then exchange ->ops with one that has only a
> release function. We don't need anything else as long as all fence_*
> functions the kernel might call check for signalling correctly first
> (fence_wait is broken at least).
> 
> Or we just give up (for now) and declare module unload as slightly racy.
> dma-buf is similar. An intermediate option might be to at least add a
> THIS_MODULE reference to each fence (but that's a bit expensive ...).

I'd say we just give up for now as we don't have any driver using
timeline_destroy for now. So we could go for other improvements first.

> - back to timeline vs. context: I have no idea how to best clean up this
>   mess, but least painful option long-term is probably to switch over all
>   current users of fence_context_alloc to timelines and remove the plain
>   context interface.

Agreed.

> 
> - Imo the interface in include/linux/sync.h is duplicating too much of
>   fence.h. I think the only bits we need are the refcounting, creating,
>   fd-install and that's it. Plus a macro to loop over all the fences in a
>   sync_fence. With that drivers will only ever deal with a pile of
>   struct fence, making implicit fencing (using the fence list in dma-buf)
>   and explicit fencing (using the fence list in sync_fence) much more
>   similar.

Yes, most of the sync_fence waiting should not be exported. Drivers
should only wait for fence imo, not sync_fences.

> 
>   And we can easily do that since no internal users ;-)
> 
> - get_timeline_name and get_driver_name are imo too much indirection, just
>   add ->(drv_)name field to each of these.
> 
> - struct sync_fence is a major confusion imo against struct fence. It
>   made much more sense in the pure-android world where fence == sync_pt.
>   Maybe we can rename sync_fence to sync_fence_fd (a bit long, and fd is a
>   bit inaccurate), sync_file (like this best), fence_file (sounds silly
>   imo), or something else?

sync_file sounds good for me. fence_file feels like it a file for a
single fence but we may have many fences on one sync_file.

> 
> - I guess just not yet part of this rfc, but moving the testsuite and
>   adding kerneldoc for this is planned I guess? If you feel like I think
>   it'd be best. We pull the current dma-buf stuff into
>   device-drivers.tmpl, but it's completely lacking overview docs and all
>   that. And I'd like to duplicate at least the dma-buf/fence sections into
>   the gpu.tmpl docbook.

We have converted testsuite from android's libsync but we need to wait
for Google to re-license it to send it upstream.

kerneldoc is planned for sure, but I'd say it will be better to have
some users first, DRM for example.

> 
> - If we make timelines first class objects I think we could move some of
>   the fields from struct fence to struct fence_timeline. E.g. the ops
>   struct. That also makes it clearer that some of the vfuncs really should
>   be taking a struct fence_timeline *timeline instead of a struct fence
>   *fence as their primary parameter.

I'll keep that as a final goal and work RFC v2 and see how far we can
get.

	Gustavo

[toc] | [prev] | [next] | [standalone]


#1312362

FromJohn Harrison <John.C.Harrison@Intel.com>
Date2016-01-19 17:20 +0100
Message-ID<qSHaH-1Rh-17@gated-at.bofh.it>
In reply to#1312325
On 19/01/2016 15:23, Gustavo Padovan wrote:
> Hi Daniel,
>
> 2016-01-19 Daniel Vetter <daniel@ffwll.ch>:
>
>> On Fri, Jan 15, 2016 at 12:55:10PM -0200, Gustavo Padovan wrote:
>>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>>
>>> This patch series de-stage the sync framework, and in order to accomplish that
>>> a bunch of cleanups/improvements on the sync and fence were made.
>>>
>>> The sync framework contained some abstractions around struct fence and those
>>> were removed in the de-staging process among other changes:
>>>
>>> Userspace visible changes
>>> -------------------------
>>>
>>>   * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
>>>   other change.
>>>
>>> Kernel API changes
>>> ------------------
>>>
>>>   * struct sync_timeline is now struct fence_timeline
>>>   * sync_timeline_ops is now fence_timeline_ops and they now carry struct
>>>   fence as parameter instead of struct sync_pt
>>>   * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
>>>   the fence_timeline is destroyed
>>>   * added fence_add_used_data() to pass a private point to struct fence. This
>>>   pointer is sent back on the .cleanup op.
>>>   * The sync timeline function were moved to be fence_timeline functions:
>>> 	 - sync_timeline_create()	-> fence_timeline_create()
>>> 	 - sync_timeline_get()		-> fence_timeline_get()
>>> 	 - sync_timeline_put()		-> fence_timeline_put()
>>> 	 - sync_timeline_destroy()	-> fence_timeline_destroy()
>>> 	 - sync_timeline_signal()	-> fence_timeline_signal()
>>>
>>>    * sync_pt_create() was replaced be fence_create_on_timeline()
>>>
>>> Internal changes
>>> ----------------
>>>
>>>   * fence_timeline_ops was removed in favor of direct use fence_ops
>>>   * fence default functions were created for fence_ops
>>>   * removed structs sync_pt, sw_sync_timeline and sw_sync_pt
>> Bunch of fairly random comments all over:
>>
>> - include/uapi/linux/sw_sync.h imo should be dropped, it's just a private
>>    debugfs interface between fence fds and the testsuite. Since the plan is
>>    to have the testcases integrated into the kernel tree too we don't need
>>    a public header.
>>
>> - similar for include/linux/sw_sync.h Imo that should all be moved into
>>    sync_debug.c. Same for sw_sync.c, that should all land in sync_debug
>>    imo, and made optional with a Kconfig option. At least we should reuse
>>    CONFIG_DEBUGFS.
> These two items sounds reasonable to me.

I have just posted our in-progress IGT for testing i915 syncs (with a CC 
of Gustavo). It uses the sw_sync mechanisms. Can you take a quick look 
and see if it is the kind of thing you would expect us to be doing? Or 
is it using interfaces that you are planning to remove and/or make 
kernel only?

I'm not sure having a kernel only test is the best way to go. Having 
user land tests like IGT would be much more versatile.


>> - fence_context and fence_timeline are really the same. timeline has some
>>    super-basic support for doing sw-only fence timelines, but imo that's
>>    not really worth keeping (and if so better to keep seperate in a
>>    sw-fence.c or similar, like seqno-fence.c). The other main thing
>>    timeline provides is support to clean up fences on a timeline. And imo
>>    that cleanup should be done by the core fence support, not by the add-on
>>    stuff.
> Yes, they are. But I currently doesn't know how to merge them best, so I
> decided to go for a RFC instead of trying some crazy solution touching
> all fence_context users.
>
>> Interlude about fence cleanup on driver unload:
>>
>> Working drivers imo should never call timeline_destroy when there's still
>> an unsignalled fence around for that timeline/context. That just means
>> they're broken and failed to clean up all the pending work. So the problem
>> really is only what to do with fences where the driver disappeared, and
>> for that we essentially need a fence_revoke() function (which could be
>> called internally from timeline_free). So here's what I think
>> timeline_free should do:
>>
>> for_each_fence_on_timel() {
>> 	WARN_ON(!fence_is_signalled());
>>
>> 	fence_revoke(fence);
>> }
>>
>> Implementing fence_revoke is a bit tricky since we need to make sure the
>> memory contained ->ops and similar stuff doesn't disappear. Simplest
>> option might be to grab a temporary reference (using
>> kref_get_unless_zero), and then exchange ->ops with one that has only a
>> release function. We don't need anything else as long as all fence_*
>> functions the kernel might call check for signalling correctly first
>> (fence_wait is broken at least).
>>
>> Or we just give up (for now) and declare module unload as slightly racy.
>> dma-buf is similar. An intermediate option might be to at least add a
>> THIS_MODULE reference to each fence (but that's a bit expensive ...).
> I'd say we just give up for now as we don't have any driver using
> timeline_destroy for now. So we could go for other improvements first.
>
>> - back to timeline vs. context: I have no idea how to best clean up this
>>    mess, but least painful option long-term is probably to switch over all
>>    current users of fence_context_alloc to timelines and remove the plain
>>    context interface.
> Agreed.
>
>> - Imo the interface in include/linux/sync.h is duplicating too much of
>>    fence.h. I think the only bits we need are the refcounting, creating,
>>    fd-install and that's it. Plus a macro to loop over all the fences in a
>>    sync_fence. With that drivers will only ever deal with a pile of
>>    struct fence, making implicit fencing (using the fence list in dma-buf)
>>    and explicit fencing (using the fence list in sync_fence) much more
>>    similar.
> Yes, most of the sync_fence waiting should not be exported. Drivers
> should only wait for fence imo, not sync_fences.
>
>>    And we can easily do that since no internal users ;-)
>>
>> - get_timeline_name and get_driver_name are imo too much indirection, just
>>    add ->(drv_)name field to each of these.
>>
>> - struct sync_fence is a major confusion imo against struct fence. It
>>    made much more sense in the pure-android world where fence == sync_pt.
>>    Maybe we can rename sync_fence to sync_fence_fd (a bit long, and fd is a
>>    bit inaccurate), sync_file (like this best), fence_file (sounds silly
>>    imo), or something else?
> sync_file sounds good for me. fence_file feels like it a file for a
> single fence but we may have many fences on one sync_file.
>
>> - I guess just not yet part of this rfc, but moving the testsuite and
>>    adding kerneldoc for this is planned I guess? If you feel like I think
>>    it'd be best. We pull the current dma-buf stuff into
>>    device-drivers.tmpl, but it's completely lacking overview docs and all
>>    that. And I'd like to duplicate at least the dma-buf/fence sections into
>>    the gpu.tmpl docbook.
> We have converted testsuite from android's libsync but we need to wait
> for Google to re-license it to send it upstream.
>
> kerneldoc is planned for sure, but I'd say it will be better to have
> some users first, DRM for example.
>
>> - If we make timelines first class objects I think we could move some of
>>    the fields from struct fence to struct fence_timeline. E.g. the ops
>>    struct. That also makes it clearer that some of the vfuncs really should
>>    be taking a struct fence_timeline *timeline instead of a struct fence
>>    *fence as their primary parameter.
> I'll keep that as a final goal and work RFC v2 and see how far we can
> get.
>
> 	Gustavo

[toc] | [prev] | [next] | [standalone]


#1312408

FromGustavo Padovan <gustavo@padovan.org>
Date2016-01-19 19:00 +0100
Message-ID<qSIJt-2KR-19@gated-at.bofh.it>
In reply to#1312362
2016-01-19 John Harrison <John.C.Harrison@Intel.com>:

> On 19/01/2016 15:23, Gustavo Padovan wrote:
> >Hi Daniel,
> >
> >2016-01-19 Daniel Vetter <daniel@ffwll.ch>:
> >
> >>On Fri, Jan 15, 2016 at 12:55:10PM -0200, Gustavo Padovan wrote:
> >>>From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >>>
> >>>This patch series de-stage the sync framework, and in order to accomplish that
> >>>a bunch of cleanups/improvements on the sync and fence were made.
> >>>
> >>>The sync framework contained some abstractions around struct fence and those
> >>>were removed in the de-staging process among other changes:
> >>>
> >>>Userspace visible changes
> >>>-------------------------
> >>>
> >>>  * The sw_sync file was moved from /dev/sw_sync to <debugfs>/sync/sw_sync. No
> >>>  other change.
> >>>
> >>>Kernel API changes
> >>>------------------
> >>>
> >>>  * struct sync_timeline is now struct fence_timeline
> >>>  * sync_timeline_ops is now fence_timeline_ops and they now carry struct
> >>>  fence as parameter instead of struct sync_pt
> >>>  * a .cleanup() fence op was added to allow sync_fence to run a cleanup when
> >>>  the fence_timeline is destroyed
> >>>  * added fence_add_used_data() to pass a private point to struct fence. This
> >>>  pointer is sent back on the .cleanup op.
> >>>  * The sync timeline function were moved to be fence_timeline functions:
> >>>	 - sync_timeline_create()	-> fence_timeline_create()
> >>>	 - sync_timeline_get()		-> fence_timeline_get()
> >>>	 - sync_timeline_put()		-> fence_timeline_put()
> >>>	 - sync_timeline_destroy()	-> fence_timeline_destroy()
> >>>	 - sync_timeline_signal()	-> fence_timeline_signal()
> >>>
> >>>   * sync_pt_create() was replaced be fence_create_on_timeline()
> >>>
> >>>Internal changes
> >>>----------------
> >>>
> >>>  * fence_timeline_ops was removed in favor of direct use fence_ops
> >>>  * fence default functions were created for fence_ops
> >>>  * removed structs sync_pt, sw_sync_timeline and sw_sync_pt
> >>Bunch of fairly random comments all over:
> >>
> >>- include/uapi/linux/sw_sync.h imo should be dropped, it's just a private
> >>   debugfs interface between fence fds and the testsuite. Since the plan is
> >>   to have the testcases integrated into the kernel tree too we don't need
> >>   a public header.
> >>
> >>- similar for include/linux/sw_sync.h Imo that should all be moved into
> >>   sync_debug.c. Same for sw_sync.c, that should all land in sync_debug
> >>   imo, and made optional with a Kconfig option. At least we should reuse
> >>   CONFIG_DEBUGFS.
> >These two items sounds reasonable to me.
> 
> I have just posted our in-progress IGT for testing i915 syncs (with a CC of
> Gustavo). It uses the sw_sync mechanisms. Can you take a quick look and see
> if it is the kind of thing you would expect us to be doing? Or is it using
> interfaces that you are planning to remove and/or make kernel only?
> 
> I'm not sure having a kernel only test is the best way to go. Having user
> land tests like IGT would be much more versatile.

I agree with you, we should allow IGT and other test tools to access
sw_sync. include/linux/sw_sync.h can be kept private, but the uapi one
needs wil be needed for testing, unless we replicate the header file
inside IGT, but not sure if it is a good idea.

	Gustavo

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web