summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2025-01-09 10:55:53 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-01-23 17:21:16 +0100
commitc5418187b97780749688d6133d2a43c37e46604e (patch)
tree3b61e4c1a1c7c711654a3ad86b4ce48ccda44b04
parentbc9c49341f9728c31fe248c5fbba32d2e81a092b (diff)
downloadlinux-c5418187b97780749688d6133d2a43c37e46604e.tar.gz
linux-c5418187b97780749688d6133d2a43c37e46604e.tar.bz2
linux-c5418187b97780749688d6133d2a43c37e46604e.zip
nouveau/fence: handle cross device fences properly
commit 1f9910b41c857a892b83801feebdc7bdf38c5985 upstream. The fence sync logic doesn't handle a fence sync across devices as it tries to write to a channel offset from one device into the fence bo from a different device, which won't work so well. This patch fixes that to avoid using the sync path in the case where the fences come from different nouveau drm devices. This works fine on a single device as the fence bo is shared across the devices, and mapped into each channels vma space, the channel offsets are therefore okay to pass between sides, so one channel can sync on the seqnos from the other by using the offset into it's vma. Signed-off-by: Dave Airlie <airlied@redhat.com> Cc: stable@vger.kernel.org Reviewed-by: Ben Skeggs <bskeggs@nvidia.com> [ Fix compilation issue; remove version log from commit messsage. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20250109005553.623947-1-airlied@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 93f08f9479d8..03eacb22648e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -386,11 +386,13 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
if (f) {
struct nouveau_channel *prev;
bool must_wait = true;
+ bool local;
rcu_read_lock();
prev = rcu_dereference(f->channel);
- if (prev && (prev == chan ||
- fctx->sync(f, prev, chan) == 0))
+ local = prev && prev->cli->drm == chan->cli->drm;
+ if (local && (prev == chan ||
+ fctx->sync(f, prev, chan) == 0))
must_wait = false;
rcu_read_unlock();
if (!must_wait)