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

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
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
{
	struct dma_fence_array *result;
	struct dma_fence *tmp, **array;
	ktime_t timestamp;
	unsigned int i;
	size_t count;

	count = 0;
	timestamp = ns_to_ktime(0);
	for (i = 0; i < num_fences; ++i) {
		dma_fence_unwrap_for_each(tmp, &iter[i], fences[i])
			if (!dma_fence_is_signaled(tmp))
		dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) {
			if (!dma_fence_is_signaled(tmp)) {
				++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)
		return dma_fence_get_stub();
		return dma_fence_allocate_private_stub(timestamp);

	array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
	if (!array)
@@ -138,7 +156,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
	} while (tmp);

	if (count == 0) {
		tmp = dma_fence_get_stub();
		tmp = dma_fence_allocate_private_stub(ktime_get());
		goto return_tmp;
	}

+3 −2
Original line number Diff line number Diff line
@@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub);

/**
 * 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.
 */
struct dma_fence *dma_fence_allocate_private_stub(void)
struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp)
{
	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,
		&fence->flags);

	dma_fence_signal(fence);
	dma_fence_signal_timestamp(fence, timestamp);

	return fence;
}
+1 −1
Original line number Diff line number Diff line
@@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence);
 */
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))
		return PTR_ERR(fence);
+1 −1
Original line number Diff line number Diff line
@@ -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);

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);

extern const struct dma_fence_ops dma_fence_array_ops;