Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.

dma_fence_chain_find_seqno only ever returns the top fence in the
chain or an unsignalled fence. Hence if we request a seqno that
is already signalled it returns a NULL fence. Some callers are
not prepared to handle this, like the syncobj transfer functions
for example.

This behavior is "new" with timeline syncobj and it looks like
not all callers were updated. To fix this behavior make sure
that a successful drm_sync_find_fence always returns a non-NULL
fence.

v2: Move the fix to drm_syncobj_find_fence from the transfer
functions.

Fixes: ea569910cbab ("drm/syncobj: add transition iotcls between binary and timeline v2")
Cc: stable@vger.kernel.org
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Christian König <christian.koenig@amd.com>
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211208023935.17018-1-bas@basnieuwenhuizen.nl

authored by

Bas Nieuwenhuizen and committed by
Christian König
b19926d4 e485382e

+10 -1
+10 -1
drivers/gpu/drm/drm_syncobj.c
··· 404 404 405 405 if (*fence) { 406 406 ret = dma_fence_chain_find_seqno(fence, point); 407 - if (!ret) 407 + if (!ret) { 408 + /* If the requested seqno is already signaled 409 + * drm_syncobj_find_fence may return a NULL 410 + * fence. To make sure the recipient gets 411 + * signalled, use a new fence instead. 412 + */ 413 + if (!*fence) 414 + *fence = dma_fence_get_stub(); 415 + 408 416 goto out; 417 + } 409 418 dma_fence_put(*fence); 410 419 } else { 411 420 ret = -EINVAL;