Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7104568 authored by Christian König's avatar Christian König Committed by Daniel Vetter
Browse files

dma-buf/fence: add signal_on_any to the fence array v2



If @signal_on_any is true the fence array signals if any fence in the array
signals, otherwise it signals when all fences in the array signal.

v2: fix signaled test and add comment suggested by Chris Wilson.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
Acked-by: default avatarSumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1464786612-5010-4-git-send-email-deathsimple@vodafone.de
parent b3dfbdf2
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ static void fence_array_cb_func(struct fence *f, struct fence_cb *cb)

	if (atomic_dec_and_test(&array->num_pending))
		fence_signal(&array->base);
	fence_put(&array->base);
}

static bool fence_array_enable_signaling(struct fence *fence)
@@ -51,11 +52,22 @@ static bool fence_array_enable_signaling(struct fence *fence)

	for (i = 0; i < array->num_fences; ++i) {
		cb[i].array = array;
		/*
		 * As we may report that the fence is signaled before all
		 * callbacks are complete, we need to take an additional
		 * reference count on the array so that we do not free it too
		 * early. The core fence handling will only hold the reference
		 * until we signal the array as complete (but that is now
		 * insufficient).
		 */
		fence_get(&array->base);
		if (fence_add_callback(array->fences[i], &cb[i].cb,
				       fence_array_cb_func))
				       fence_array_cb_func)) {
			fence_put(&array->base);
			if (atomic_dec_and_test(&array->num_pending))
				return false;
		}
	}

	return true;
}
@@ -64,7 +76,7 @@ static bool fence_array_signaled(struct fence *fence)
{
	struct fence_array *array = to_fence_array(fence);

	return atomic_read(&array->num_pending) == 0;
	return atomic_read(&array->num_pending) <= 0;
}

static void fence_array_release(struct fence *fence)
@@ -94,6 +106,7 @@ const struct fence_ops fence_array_ops = {
 * @fences:		[in]	array containing the fences
 * @context:		[in]	fence context to use
 * @seqno:		[in]	sequence number to use
 * @signal_on_any	[in]	signal on any fence in the array
 *
 * Allocate a fence_array object and initialize the base fence with fence_init().
 * In case of error it returns NULL.
@@ -101,9 +114,13 @@ const struct fence_ops fence_array_ops = {
 * The caller should allocte the fences array with num_fences size
 * and fill it with the fences it wants to add to the object. Ownership of this
 * array is take and fence_put() is used on each fence on release.
 *
 * If @signal_on_any is true the fence array signals if any fence in the array
 * signals, otherwise it signals when all fences in the array signal.
 */
struct fence_array *fence_array_create(int num_fences, struct fence **fences,
				       u64 context, unsigned seqno)
				       u64 context, unsigned seqno,
				       bool signal_on_any)
{
	struct fence_array *array;
	size_t size = sizeof(*array);
@@ -119,7 +136,7 @@ struct fence_array *fence_array_create(int num_fences, struct fence **fences,
		   context, seqno);

	array->num_fences = num_fences;
	atomic_set(&array->num_pending, num_fences);
	atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences);
	array->fences = fences;

	return array;
+2 −1
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ static inline struct fence_array *to_fence_array(struct fence *fence)
}

struct fence_array *fence_array_create(int num_fences, struct fence **fences,
				       u64 context, unsigned seqno);
				       u64 context, unsigned seqno,
				       bool signal_on_any);

#endif /* __LINUX_FENCE_ARRAY_H */