Am 04.11.2016 um 21:16 schrieb Alex Deucher: > From: "monk.liu" <monk.liu at amd.com> > > Return the index of the first signaled fence. This information > is useful in some APIs like Vulkan. > > v2: rebase on drm-next (fence -> dma_fence) > > Signed-off-by: monk.liu <monk.liu at amd.com> > Signed-off-by: Alex Deucher <alexander.deucher at amd.com> > Cc: Sumit Semwal <sumit.semwal at linaro.org> Both patches are Reviewed-by: Christian König <christian.koenig at amd.com>. > --- > > This is the same patch set I send out yesterday, I just > squashed the amdgpu patches together and rebased everything on > the fence -> dma_fence renaming. This is used by our VK driver > and we are planning to use it in mesa as well. > > drivers/dma-buf/dma-fence.c | 20 +++++++++++++++----- > include/linux/dma-fence.h | 2 +- > 2 files changed, 16 insertions(+), 6 deletions(-) > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index 9ef3c2f..dd00990 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -402,14 +402,18 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) > EXPORT_SYMBOL(dma_fence_default_wait); > > static bool > -dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) > +dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count, > + uint32_t *idx) > { > int i; > > for (i = 0; i < count; ++i) { > struct dma_fence *fence = fences[i]; > - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) > + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { > + if (idx) > + *idx = i; > return true; > + } > } > return false; > } > @@ -421,6 +425,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) > * @count: [in] number of fences to wait on > * @intr: [in] if true, do an interruptible wait > * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT > + * @idx: [out] the first signaled fence index, meaninful only on Returns positive > * > * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if > * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies > @@ -432,7 +437,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) > */ > signed long > dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, > - bool intr, signed long timeout) > + bool intr, signed long timeout, uint32_t *idx) > { > struct default_wait_cb *cb; > signed long ret = timeout; > @@ -443,8 +448,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, > > if (timeout == 0) { > for (i = 0; i < count; ++i) > - if (dma_fence_is_signaled(fences[i])) > + if (dma_fence_is_signaled(fences[i])) { > + if (idx) > + *idx = i; > return 1; > + } > > return 0; > } > @@ -467,6 +475,8 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, > if (dma_fence_add_callback(fence, &cb[i].base, > dma_fence_default_wait_cb)) { > /* This fence is already signaled */ > + if (idx) > + *idx = i; > goto fence_rm_cb; > } > } > @@ -477,7 +487,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, > else > set_current_state(TASK_UNINTERRUPTIBLE); > > - if (dma_fence_test_signaled_any(fences, count)) > + if (dma_fence_test_signaled_any(fences, count, idx)) > break; > > ret = schedule_timeout(ret); > diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h > index ba60c04..e578fe7 100644 > --- a/include/linux/dma-fence.h > +++ b/include/linux/dma-fence.h > @@ -382,7 +382,7 @@ signed long dma_fence_wait_timeout(struct dma_fence *, > bool intr, signed long timeout); > signed long dma_fence_wait_any_timeout(struct dma_fence **fences, > uint32_t count, > - bool intr, signed long timeout); > + bool intr, signed long timeout, uint32_t *idx); > > /** > * dma_fence_wait - sleep until the fence gets signaled