Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/syncobj: use the timeline point in drm_syncobj_find_fence v4



Implement finding the right timeline point in drm_syncobj_find_fence.

v2: return -EINVAL when the point is not submitted yet.
v3: fix reference counting bug, add flags handling as well
v4: add timeout for find fence

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarLionel Landwerlin <lionel.g.landwerlin@intel.com>
Link: https://patchwork.freedesktop.org/patch/295786/?series=58813&rev=1
parent 27b575a9
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -214,6 +214,8 @@ static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
	dma_fence_put(fence);
}

/* 5s default for wait submission */
#define DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT 5000000000ULL
/**
 * drm_syncobj_find_fence - lookup and reference the fence in a sync object
 * @file_private: drm file private pointer
@@ -234,16 +236,58 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
			   struct dma_fence **fence)
{
	struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
	int ret = 0;
	struct syncobj_wait_entry wait;
	u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT);
	int ret;

	if (!syncobj)
		return -ENOENT;

	*fence = drm_syncobj_fence_get(syncobj);
	if (!*fence) {
	drm_syncobj_put(syncobj);

	if (*fence) {
		ret = dma_fence_chain_find_seqno(fence, point);
		if (!ret)
			return 0;
		dma_fence_put(*fence);
	} else {
		ret = -EINVAL;
	}
	drm_syncobj_put(syncobj);

	if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
		return ret;

	memset(&wait, 0, sizeof(wait));
	wait.task = current;
	wait.point = point;
	drm_syncobj_fence_add_wait(syncobj, &wait);

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		if (wait.fence) {
			ret = 0;
			break;
		}
                if (timeout == 0) {
                        ret = -ETIME;
                        break;
                }

		if (signal_pending(current)) {
			ret = -ERESTARTSYS;
			break;
		}

                timeout = schedule_timeout(timeout);
	} while (1);

	__set_current_state(TASK_RUNNING);
	*fence = wait.fence;

	if (wait.node.next)
		drm_syncobj_remove_wait(syncobj, &wait);

	return ret;
}
EXPORT_SYMBOL(drm_syncobj_find_fence);