All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gustavo Padovan <gustavo@padovan.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org,
	dri-devel@lists.freedesktop.org, daniels@collabora.com,
	"Arve Hjønnevåg" <arve@android.com>,
	"Riley Andrews" <riandrews@android.com>,
	"Daniel Vetter" <daniel.vetter@ffwll.ch>,
	"Rob Clark" <robdclark@gmail.com>,
	"Greg Hackmann" <ghackmann@google.com>,
	"John Harrison" <John.C.Harrison@Intel.com>,
	"Maarten Lankhorst" <maarten.lankhorst@canonical.com>,
	"Gustavo Padovan" <gustavo.padovan@collabora.co.uk>
Subject: [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline
Date: Fri, 15 Jan 2016 12:55:21 -0200	[thread overview]
Message-ID: <1452869739-3304-12-git-send-email-gustavo@padovan.org> (raw)
In-Reply-To: <1452869739-3304-1-git-send-email-gustavo@padovan.org>

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

WARNING: multiple messages have this Message-ID (diff)
From: Gustavo Padovan <gustavo@padovan.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: devel@driverdev.osuosl.org, daniels@collabora.com,
	"Daniel Vetter" <daniel.vetter@ffwll.ch>,
	"Riley Andrews" <riandrews@android.com>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	"Arve Hjønnevåg" <arve@android.com>,
	"Maarten Lankhorst" <maarten.lankhorst@canonical.com>,
	"Gustavo Padovan" <gustavo.padovan@collabora.co.uk>,
	"John Harrison" <John.C.Harrison@Intel.com>
Subject: [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline
Date: Fri, 15 Jan 2016 12:55:21 -0200	[thread overview]
Message-ID: <1452869739-3304-12-git-send-email-gustavo@padovan.org> (raw)
In-Reply-To: <1452869739-3304-1-git-send-email-gustavo@padovan.org>

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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2016-01-15 15:01 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-15 14:55 [RFC 00/29] De-stage android's sync framework Gustavo Padovan
2016-01-15 14:55 ` [RFC 01/29] staging/android: fix sync framework documentation Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 02/29] staging/android: fix checkpatch warning Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 03/29] staging/android: rename sync_fence_release Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 04/29] staging/android: rename 'android_fence' to 'sync_fence' Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 05/29] staging/android: remove not used sync_timeline ops Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 06/29] staging/android: create a 'sync' dir for debugfs information Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 07/29] staging/android: move sw_sync file to debugfs file Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 08/29] staging/android: Remove WARN_ON_ONCE when releasing sync_fence Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 09/29] staging/android: rename struct sync_fence's variables to 'sync_fence' Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 10/29] staging/android: rename 'sync_pt' to 'fence' in struct sync_fence_cb Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` Gustavo Padovan [this message]
2016-01-15 14:55   ` [RFC 11/29] dma-buf/fence: move sync_timeline to fence_timeline Gustavo Padovan
2016-01-20  0:56   ` Greg Hackmann
2016-01-20  0:56     ` Greg Hackmann
2016-01-15 14:55 ` [RFC 12/29] staging/android: remove struct sync_pt Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 13/29] dma-buf/fence: create fence_default_enable_signaling() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 14/29] dma-buf/fence: create fence_default_release() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 15/29] dma-buf/fence: create fence_default_get_driver_name() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 16/29] dma-buf/fence: create fence_default_timeline_name() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 17/29] dma-buf/fence: store last signaled value on fence timeline Gustavo Padovan
2016-01-15 14:55 ` [RFC 18/29] dma-buf/fence: create default .fence_value_str() and .timeline_value_str() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 19/29] dma-buf/fence: create fence_default_fill_driver_data() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 20/29] dma-buf/fence: remove fence_timeline_ops Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 21/29] dma-buf/fence: add fence_create_on_timeline() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 22/29] staging/android: remove sync_pt_create() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 23/29] staging/android: remove sw_sync_timeline and sw_sync_pt Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 24/29] dma-buf/fence: add debug to fence timeline Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 25/29] dma-buf/fence: remove unused var from fence_timeline_signal() Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 26/29] dma-buf/fence: remove pointless fence_timeline_signal at destroy phase Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 17:48   ` John Harrison
2016-01-15 18:02     ` Gustavo Padovan
2016-01-15 23:42       ` Greg Hackmann
2016-01-15 23:42         ` Greg Hackmann
2016-02-09 22:55         ` Tom Cherry
2016-02-09 22:55           ` Tom Cherry
2016-02-25 15:26           ` Gustavo Padovan
2016-02-25 15:26             ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 27/29] dma-buf/fence: add .cleanup() callback Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 28/29] staging/android: use .cleanup() to interrupt any sync_fence waiter Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 14:55 ` [RFC 29/29] dma-buf/fence: de-stage sync framework Gustavo Padovan
2016-01-15 14:55   ` Gustavo Padovan
2016-01-15 19:11 ` [RFC 00/29] De-stage android's " Joe Perches
2016-01-19 11:00 ` Daniel Vetter
2016-01-19 11:00   ` Daniel Vetter
2016-01-19 15:23   ` Gustavo Padovan
2016-01-19 15:23     ` Gustavo Padovan
2016-01-19 16:12     ` John Harrison
2016-01-19 17:52       ` Gustavo Padovan
2016-01-19 17:52         ` Gustavo Padovan
2016-01-19 18:04         ` Daniel Vetter
2016-01-19 18:04           ` Daniel Vetter
2016-01-19 18:15           ` Gustavo Padovan
2016-03-23 15:07       ` Tomeu Vizoso
2016-03-23 15:07         ` Tomeu Vizoso
2016-01-19 20:10   ` Gustavo Padovan
2016-01-19 20:10     ` Gustavo Padovan
2016-01-19 20:32     ` Daniel Vetter
2016-01-19 20:32       ` Daniel Vetter
2016-01-20 10:28 ` Maarten Lankhorst
2016-01-20 14:32   ` Gustavo Padovan
2016-01-20 14:32     ` Gustavo Padovan
2016-01-20 15:02     ` Maarten Lankhorst
2016-01-20 15:02       ` Maarten Lankhorst
2016-01-20 16:29       ` Daniel Vetter
2016-01-20 16:29         ` Daniel Vetter
2016-01-20 18:28       ` Gustavo Padovan
2016-01-20 18:28         ` Gustavo Padovan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1452869739-3304-12-git-send-email-gustavo@padovan.org \
    --to=gustavo@padovan.org \
    --cc=John.C.Harrison@Intel.com \
    --cc=arve@android.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=daniels@collabora.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ghackmann@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=gustavo.padovan@collabora.co.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@canonical.com \
    --cc=riandrews@android.com \
    --cc=robdclark@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.