]> Git Repo - linux.git/commitdiff
drm/xe: Make irq enabled flag atomic
authorIlia Levi <[email protected]>
Tue, 10 Dec 2024 17:35:06 +0000 (19:35 +0200)
committerRodrigo Vivi <[email protected]>
Wed, 11 Dec 2024 18:20:53 +0000 (13:20 -0500)
The irq.enabled flag was protected by a spin lock (irq.lock).
By making it atomic we no longer need to wait for the spin lock in
irq handlers. This will become especially useful for MSI-X irq
handlers to prevent lock contention between different interrupts.

Signed-off-by: Ilia Levi <[email protected]>
Reviewed-by: Rodrigo Vivi <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Signed-off-by: Rodrigo Vivi <[email protected]>
drivers/gpu/drm/xe/display/ext/i915_irq.c
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_irq.c

index a7dbc6554d694483e542d5fab20c34cfe3a7efbf..ac4cda2d81c7a1fa5b707cd1af98283bd03e3d71 100644 (file)
@@ -53,18 +53,7 @@ void gen2_irq_init(struct intel_uncore *uncore, struct i915_irq_regs regs,
 
 bool intel_irqs_enabled(struct xe_device *xe)
 {
-       /*
-        * XXX: i915 has a racy handling of the irq.enabled, since it doesn't
-        * lock its transitions. Because of that, the irq.enabled sometimes
-        * is not read with the irq.lock in place.
-        * However, the most critical cases like vblank and page flips are
-        * properly using the locks.
-        * We cannot take the lock in here or run any kind of assert because
-        * of i915 inconsistency.
-        * But at this point the xe irq is better protected against races,
-        * although the full solution would be protecting the i915 side.
-        */
-       return xe->irq.enabled;
+       return atomic_read(&xe->irq.enabled);
 }
 
 void intel_synchronize_irq(struct xe_device *xe)
index 1373a222f5a5ca41e27389264b3400f69393655a..ace22e35e769175888ed849e3c288d589e1ff84b 100644 (file)
@@ -347,7 +347,7 @@ struct xe_device {
                spinlock_t lock;
 
                /** @irq.enabled: interrupts enabled on this device */
-               bool enabled;
+               atomic_t enabled;
        } irq;
 
        /** @ttm: ttm device */
index 7bf7201529ac82cfeda4ed5382718137c99e1c5d..1c509e66694d74a154601d8f50ccdf875f0a970f 100644 (file)
@@ -348,12 +348,8 @@ static irqreturn_t xelp_irq_handler(int irq, void *arg)
        unsigned long intr_dw[2];
        u32 identity[32];
 
-       spin_lock(&xe->irq.lock);
-       if (!xe->irq.enabled) {
-               spin_unlock(&xe->irq.lock);
+       if (!atomic_read(&xe->irq.enabled))
                return IRQ_NONE;
-       }
-       spin_unlock(&xe->irq.lock);
 
        master_ctl = xelp_intr_disable(xe);
        if (!master_ctl) {
@@ -417,12 +413,8 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg)
 
        /* TODO: This really shouldn't be copied+pasted */
 
-       spin_lock(&xe->irq.lock);
-       if (!xe->irq.enabled) {
-               spin_unlock(&xe->irq.lock);
+       if (!atomic_read(&xe->irq.enabled))
                return IRQ_NONE;
-       }
-       spin_unlock(&xe->irq.lock);
 
        master_tile_ctl = dg1_intr_disable(xe);
        if (!master_tile_ctl) {
@@ -644,12 +636,8 @@ static irqreturn_t vf_mem_irq_handler(int irq, void *arg)
        struct xe_tile *tile;
        unsigned int id;
 
-       spin_lock(&xe->irq.lock);
-       if (!xe->irq.enabled) {
-               spin_unlock(&xe->irq.lock);
+       if (!atomic_read(&xe->irq.enabled))
                return IRQ_NONE;
-       }
-       spin_unlock(&xe->irq.lock);
 
        for_each_tile(tile, xe, id)
                xe_memirq_handler(&tile->memirq);
@@ -674,10 +662,9 @@ static void irq_uninstall(void *arg)
        struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
        int irq;
 
-       if (!xe->irq.enabled)
+       if (!atomic_xchg(&xe->irq.enabled, 0))
                return;
 
-       xe->irq.enabled = false;
        xe_irq_reset(xe);
 
        irq = pci_irq_vector(pdev, 0);
@@ -724,7 +711,7 @@ int xe_irq_install(struct xe_device *xe)
                return err;
        }
 
-       xe->irq.enabled = true;
+       atomic_set(&xe->irq.enabled, 1);
 
        xe_irq_postinstall(xe);
 
@@ -744,9 +731,7 @@ void xe_irq_suspend(struct xe_device *xe)
 {
        int irq = to_pci_dev(xe->drm.dev)->irq;
 
-       spin_lock_irq(&xe->irq.lock);
-       xe->irq.enabled = false; /* no new irqs */
-       spin_unlock_irq(&xe->irq.lock);
+       atomic_set(&xe->irq.enabled, 0); /* no new irqs */
 
        synchronize_irq(irq); /* flush irqs */
        xe_irq_reset(xe); /* turn irqs off */
@@ -762,7 +747,7 @@ void xe_irq_resume(struct xe_device *xe)
         * 1. no irq will arrive before the postinstall
         * 2. display is not yet resumed
         */
-       xe->irq.enabled = true;
+       atomic_set(&xe->irq.enabled, 1);
        xe_irq_reset(xe);
        xe_irq_postinstall(xe); /* turn irqs on */
 
This page took 0.148763 seconds and 4 git commands to generate.