nouveau_exec_job_submit() locks every BO mapped in the VM, then
validates the evicted ones while holding all of those locks. A client
paging a large working set back in therefore keeps the dma-resv of every
BO it shares, e.g. with the compositor it presents to, locked for as
long as that takes, stalling the other side for no reason.

Use the two-pass locking drm_gpuvm now provides. Validation moves from
after drm_gpuvm_exec_lock() into its per-pass extra.fn callback, so the
early pass validates the evicted BOs while the resident external ones
are still unlocked, and the late pass locks those and validates
anything that was evicted in the meantime. drm_gpuvm_exec_lock() falls
back to a single pass when nothing is evicted.

Validation now runs under the uvmm mutex, like it already does for bind
jobs in bind_lock_validate().

Cc: Abhinav Kumar <[email protected]>
Cc: Alice Ryhl <[email protected]>
Cc: Anna Maniscalco <[email protected]>
Cc: Antonino Maniscalco <[email protected]>
Cc: Boris Brezillon <[email protected]>
Cc: Danilo Krummrich <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Dmitry Baryshkov <[email protected]>
Cc: Jessica Zhang <[email protected]>
Cc: Jonathan Corbet <[email protected]>
Cc: Liviu Dudau <[email protected]>
Cc: Lyude Paul <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: Marijn Suijten <[email protected]>
Cc: Maxime Ripard <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Rob Clark <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Cc: Sean Paul <[email protected]>
Cc: Shuah Khan <[email protected]>
Cc: Simona Vetter <[email protected]>
Cc: Steven Price <[email protected]>
Cc: Thomas Hellström <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Signed-off-by: Matthew Brost <[email protected]>
Assisted-by: LLM
---
v3:
 - New patch (Danilo)
---
 drivers/gpu/drm/nouveau/nouveau_exec.c | 27 +++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c 
b/drivers/gpu/drm/nouveau/nouveau_exec.c
index eea6619cffaa..b9ab7da125b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_exec.c
+++ b/drivers/gpu/drm/nouveau/nouveau_exec.c
@@ -85,6 +85,18 @@
  * the corresponding VM_BIND jobs they depend on - attached to them.
  */
 
+/*
+ * Called once per pass of drm_gpuvm_exec_lock(), validating whatever that pass
+ * locked. The early pass validates the evicted BOs before the resident ones
+ * are locked, so that a BO shared with another client, e.g. a compositor, is
+ * not held locked while this job's evicted BOs are moved back in.
+ */
+static int
+nouveau_exec_job_validate(struct drm_gpuvm_exec *vme)
+{
+       return drm_gpuvm_exec_validate(vme);
+}
+
 static int
 nouveau_exec_job_submit(struct nouveau_job *job,
                        struct drm_gpuvm_exec *vme)
@@ -99,21 +111,14 @@ nouveau_exec_job_submit(struct nouveau_job *job,
        if (ret)
                return ret;
 
+       vme->two_pass = true;
+       vme->extra.fn = nouveau_exec_job_validate;
+
        nouveau_uvmm_lock(uvmm);
        ret = drm_gpuvm_exec_lock(vme);
-       if (ret) {
-               nouveau_uvmm_unlock(uvmm);
-               return ret;
-       }
        nouveau_uvmm_unlock(uvmm);
 
-       ret = drm_gpuvm_exec_validate(vme);
-       if (ret) {
-               drm_gpuvm_exec_unlock(vme);
-               return ret;
-       }
-
-       return 0;
+       return ret;
 }
 
 static void
-- 
2.34.1

Reply via email to