dma-buf: keep the signaling time of merged fences v3

Some Android CTS is testing if the signaling time keeps consistent
during merges.

v2: use the current time if the fence is still in the signaling path and
the timestamp not yet available.
v3: improve comment, fix one more case to use the correct timestamp

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230630120041.109216-1-christian.koenig@amd.com
This commit is contained in:
Christian König 2023-06-13 10:09:20 +02:00
parent 1c519980ac
commit f781f661e8
4 changed files with 27 additions and 8 deletions

View file

@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
{ {
struct dma_fence_array *result; struct dma_fence_array *result;
struct dma_fence *tmp, **array; struct dma_fence *tmp, **array;
ktime_t timestamp;
unsigned int i; unsigned int i;
size_t count; size_t count;
count = 0; count = 0;
timestamp = ns_to_ktime(0);
for (i = 0; i < num_fences; ++i) { for (i = 0; i < num_fences; ++i) {
dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) {
if (!dma_fence_is_signaled(tmp)) if (!dma_fence_is_signaled(tmp)) {
++count; ++count;
} else if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT,
&tmp->flags)) {
if (ktime_after(tmp->timestamp, timestamp))
timestamp = tmp->timestamp;
} else {
/*
* Use the current time if the fence is
* currently signaling.
*/
timestamp = ktime_get();
}
}
} }
/*
* If we couldn't find a pending fence just return a private signaled
* fence with the timestamp of the last signaled one.
*/
if (count == 0) if (count == 0)
return dma_fence_get_stub(); return dma_fence_allocate_private_stub(timestamp);
array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
if (!array) if (!array)
@ -138,7 +156,7 @@ restart:
} while (tmp); } while (tmp);
if (count == 0) { if (count == 0) {
tmp = dma_fence_get_stub(); tmp = dma_fence_allocate_private_stub(ktime_get());
goto return_tmp; goto return_tmp;
} }

View file

@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub);
/** /**
* dma_fence_allocate_private_stub - return a private, signaled fence * dma_fence_allocate_private_stub - return a private, signaled fence
* @timestamp: timestamp when the fence was signaled
* *
* Return a newly allocated and signaled stub fence. * Return a newly allocated and signaled stub fence.
*/ */
struct dma_fence *dma_fence_allocate_private_stub(void) struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp)
{ {
struct dma_fence *fence; struct dma_fence *fence;
@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void)
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
&fence->flags); &fence->flags);
dma_fence_signal(fence); dma_fence_signal_timestamp(fence, timestamp);
return fence; return fence;
} }

View file

@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence);
*/ */
static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
{ {
struct dma_fence *fence = dma_fence_allocate_private_stub(); struct dma_fence *fence = dma_fence_allocate_private_stub(ktime_get());
if (IS_ERR(fence)) if (IS_ERR(fence))
return PTR_ERR(fence); return PTR_ERR(fence);

View file

@ -606,7 +606,7 @@ static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr)
void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline); void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline);
struct dma_fence *dma_fence_get_stub(void); struct dma_fence *dma_fence_get_stub(void);
struct dma_fence *dma_fence_allocate_private_stub(void); struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp);
u64 dma_fence_context_alloc(unsigned num); u64 dma_fence_context_alloc(unsigned num);
extern const struct dma_fence_ops dma_fence_array_ops; extern const struct dma_fence_ops dma_fence_array_ops;