Commit f781f661 authored by Christian König's avatar Christian König

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: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarLuben Tuikov <luben.tuikov@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230630120041.109216-1-christian.koenig@amd.com
parent 1c519980
...@@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, ...@@ -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 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, ...@@ -138,7 +156,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
} 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;
} }
......
...@@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub); ...@@ -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) ...@@ -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;
} }
......
...@@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence); ...@@ -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);
......
...@@ -606,7 +606,7 @@ static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment