drm/i915/gt: Disarm breadcrumbs if engines are already idle
authorjsg <jsg@openbsd.org>
Mon, 24 Jun 2024 03:49:19 +0000 (03:49 +0000)
committerjsg <jsg@openbsd.org>
Mon, 24 Jun 2024 03:49:19 +0000 (03:49 +0000)
From Chris Wilson
1d2f1123a05e3e269cd7564005b0b717f2014437 in linux-6.6.y/6.6.35
70cb9188ffc75e643debf292fcddff36c9dbd4ae in mainline linux

sys/dev/pci/drm/i915/gt/intel_breadcrumbs.c

index f9d88fa..46b6d0f 100644 (file)
@@ -260,8 +260,13 @@ static void signal_irq_work(struct irq_work *work)
                i915_request_put(rq);
        }
 
+       /* Lazy irq enabling after HW submission */
        if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers))
                intel_breadcrumbs_arm_irq(b);
+
+       /* And confirm that we still want irqs enabled before we yield */
+       if (READ_ONCE(b->irq_armed) && !atomic_read(&b->active))
+               intel_breadcrumbs_disarm_irq(b);
 }
 
 struct intel_breadcrumbs *
@@ -312,13 +317,7 @@ void __intel_breadcrumbs_park(struct intel_breadcrumbs *b)
                return;
 
        /* Kick the work once more to drain the signalers, and disarm the irq */
-       irq_work_sync(&b->irq_work);
-       while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) {
-               local_irq_disable();
-               signal_irq_work(&b->irq_work);
-               local_irq_enable();
-               cond_resched();
-       }
+       irq_work_queue(&b->irq_work);
 }
 
 void intel_breadcrumbs_free(struct kref *kref)
@@ -401,7 +400,7 @@ static void insert_breadcrumb(struct i915_request *rq)
         * the request as it may have completed and raised the interrupt as
         * we were attaching it into the lists.
         */
-       if (!b->irq_armed || __i915_request_is_complete(rq))
+       if (!READ_ONCE(b->irq_armed) || __i915_request_is_complete(rq))
                irq_work_queue(&b->irq_work);
 }