mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-26 14:17:26 -04:00
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:
parent
1c519980ac
commit
f781f661e8
4 changed files with 27 additions and 8 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue