From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758197AbcFANK1 (ORCPT ); Wed, 1 Jun 2016 09:10:27 -0400 Received: from pegasos-out.vodafone.de ([80.84.1.38]:34081 "EHLO pegasos-out.vodafone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758005AbcFANKX (ORCPT ); Wed, 1 Jun 2016 09:10:23 -0400 X-Spam-Flag: NO X-Spam-Score: -0.045 Authentication-Results: rohrpostix2.prod.vfnet.de (amavisd-new); dkim=pass header.i=@vodafone.de X-DKIM: OpenDKIM Filter v2.6.8 pegasos-out.vodafone.de 45AAE5E00FE From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, daniel@ffwll.ch, chris@chris-wilson.co.uk, gustavo@padovan.org Subject: [PATCH 03/11] dma-buf/fence: add signal_on_any to the fence array v2 Date: Wed, 1 Jun 2016 15:10:04 +0200 Message-Id: <1464786612-5010-4-git-send-email-deathsimple@vodafone.de> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1464786612-5010-1-git-send-email-deathsimple@vodafone.de> References: <1464786612-5010-1-git-send-email-deathsimple@vodafone.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Christian König 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: Christian König --- drivers/dma-buf/fence-array.c | 33 +++++++++++++++++++++++++-------- include/linux/fence-array.h | 3 ++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c index 8141217..a8731c8 100644 --- a/drivers/dma-buf/fence-array.c +++ b/drivers/dma-buf/fence-array.c @@ -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,10 +52,21 @@ 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) @@ -90,10 +102,11 @@ const struct fence_ops fence_array_ops = { /** * fence_array_create - Create a custom fence array - * @num_fences: [in] number of fences to add in the array - * @fences: [in] array containing the fences - * @context: [in] fence context to use - * @seqno: [in] sequence number to use + * @num_fences: [in] number of fences to add in the array + * @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; diff --git a/include/linux/fence-array.h b/include/linux/fence-array.h index 593ab98..86baaa4 100644 --- a/include/linux/fence-array.h +++ b/include/linux/fence-array.h @@ -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 */ -- 2.5.0