drm/xe/ct: serialise fast_lock during CT disable
authorMatthew Auld <matthew.auld@intel.com>
Mon, 10 Jul 2023 09:40:44 +0000 (10:40 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:35:23 +0000 (11:35 -0500)
The fast-path CT could be running as we enter a runtime-suspend or
potentially a GT reset, however here we only use the ct->fast_lock and
not the full ct->lock. Before disabling the CT, also serialise against
the fast_lock to ensure any in-progress work finishes before we start
nuking the CT related stuff. Once we disable ct->enabled and drop the
lock, any new work should fail gracefully, and anything that was in
progress should be finished.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_guc_ct.c

index ba89db1dcfdb19b3fc7c0d6eb19ad76ba20701a7..acf488b00b6617535e7199e0d1e425d92f5f6974 100644 (file)
@@ -301,8 +301,10 @@ int xe_guc_ct_enable(struct xe_guc_ct *ct)
                goto err_out;
 
        mutex_lock(&ct->lock);
+       spin_lock_irq(&ct->fast_lock);
        ct->g2h_outstanding = 0;
        ct->enabled = true;
+       spin_unlock_irq(&ct->fast_lock);
        mutex_unlock(&ct->lock);
 
        smp_mb();
@@ -319,8 +321,10 @@ err_out:
 
 void xe_guc_ct_disable(struct xe_guc_ct *ct)
 {
-       mutex_lock(&ct->lock);
-       ct->enabled = false;
+       mutex_lock(&ct->lock); /* Serialise dequeue_one_g2h() */
+       spin_lock_irq(&ct->fast_lock); /* Serialise CT fast-path */
+       ct->enabled = false; /* Finally disable CT communication */
+       spin_unlock_irq(&ct->fast_lock);
        mutex_unlock(&ct->lock);
 
        xa_destroy(&ct->fence_lookup);