]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nouveau/fence: handle cross device fences properly
authorDave Airlie <airlied@redhat.com>
Thu, 9 Jan 2025 00:55:53 +0000 (10:55 +1000)
committerDanilo Krummrich <dakr@kernel.org>
Mon, 13 Jan 2025 14:49:49 +0000 (15:49 +0100)
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
drivers/gpu/drm/nouveau/nouveau_fence.c

index 09686d038d6053ded7922a10f9a374e8a0aea704..7cc84472cecec2c7cbf5786b83772eb1ddf4b279 100644 (file)
@@ -387,11 +387,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)