Takashi Iwai c675c0
From b19926d4f3a660a8b76e5d989ffd1168e619a5c4 Mon Sep 17 00:00:00 2001
Takashi Iwai c675c0
From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Takashi Iwai c675c0
Date: Wed, 8 Dec 2021 03:39:35 +0100
Takashi Iwai c675c0
Subject: [PATCH] drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.
Takashi Iwai c675c0
Mime-version: 1.0
Takashi Iwai c675c0
Content-type: text/plain; charset=UTF-8
Takashi Iwai c675c0
Content-transfer-encoding: 8bit
Takashi Iwai c675c0
Git-commit: b19926d4f3a660a8b76e5d989ffd1168e619a5c4
Takashi Iwai c675c0
Patch-mainline: v5.16-rc5
Takashi Iwai c675c0
References: git-fixes
Takashi Iwai c675c0
Takashi Iwai c675c0
dma_fence_chain_find_seqno only ever returns the top fence in the
Takashi Iwai c675c0
chain or an unsignalled fence. Hence if we request a seqno that
Takashi Iwai c675c0
is already signalled it returns a NULL fence. Some callers are
Takashi Iwai c675c0
not prepared to handle this, like the syncobj transfer functions
Takashi Iwai c675c0
for example.
Takashi Iwai c675c0
Takashi Iwai c675c0
This behavior is "new" with timeline syncobj and it looks like
Takashi Iwai c675c0
not all callers were updated. To fix this behavior make sure
Takashi Iwai c675c0
that a successful drm_sync_find_fence always returns a non-NULL
Takashi Iwai c675c0
fence.
Takashi Iwai c675c0
Takashi Iwai c675c0
V2: Move the fix to drm_syncobj_find_fence from the transfer    functions.
Takashi Iwai c675c0
Takashi Iwai c675c0
Fixes: ea569910cbab ("drm/syncobj: add transition iotcls between binary and timeline v2")
Takashi Iwai c675c0
Cc: stable@vger.kernel.org
Takashi Iwai c675c0
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Takashi Iwai c675c0
Reviewed-by: Christian König <christian.koenig@amd.com>
Takashi Iwai c675c0
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Takashi Iwai c675c0
Signed-off-by: Christian König <christian.koenig@amd.com>
Takashi Iwai c675c0
Link: https://patchwork.freedesktop.org/patch/msgid/20211208023935.17018-1-bas@basnieuwenhuizen.nl
Takashi Iwai c675c0
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai c675c0
Takashi Iwai c675c0
---
Takashi Iwai c675c0
 drivers/gpu/drm/drm_syncobj.c | 11 ++++++++++-
Takashi Iwai c675c0
 1 file changed, 10 insertions(+), 1 deletion(-)
Takashi Iwai c675c0
Takashi Iwai c675c0
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
Takashi Iwai c675c0
index c9a9d74f338c..c313a5b4549c 100644
Takashi Iwai c675c0
--- a/drivers/gpu/drm/drm_syncobj.c
Takashi Iwai c675c0
+++ b/drivers/gpu/drm/drm_syncobj.c
Takashi Iwai c675c0
@@ -404,8 +404,17 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
Takashi Iwai c675c0
 
Takashi Iwai c675c0
 	if (*fence) {
Takashi Iwai c675c0
 		ret = dma_fence_chain_find_seqno(fence, point);
Takashi Iwai c675c0
-		if (!ret)
Takashi Iwai c675c0
+		if (!ret) {
Takashi Iwai c675c0
+			/* If the requested seqno is already signaled
Takashi Iwai c675c0
+			 * drm_syncobj_find_fence may return a NULL
Takashi Iwai c675c0
+			 * fence. To make sure the recipient gets
Takashi Iwai c675c0
+			 * signalled, use a new fence instead.
Takashi Iwai c675c0
+			 */
Takashi Iwai c675c0
+			if (!*fence)
Takashi Iwai c675c0
+				*fence = dma_fence_get_stub();
Takashi Iwai c675c0
+
Takashi Iwai c675c0
 			goto out;
Takashi Iwai c675c0
+		}
Takashi Iwai c675c0
 		dma_fence_put(*fence);
Takashi Iwai c675c0
 	} else {
Takashi Iwai c675c0
 		ret = -EINVAL;
Takashi Iwai c675c0
-- 
Takashi Iwai c675c0
2.31.1
Takashi Iwai c675c0