On Thu, Aug 27, 2026 at 03:47:56PM +0530, Arvind Yadav wrote:
> Wedge isolation suspends interrupts from a worker. This can race with
> PM resume and allow resume to enable interrupts after isolation has
> disabled them.
> 
> Add a managed mutex around IRQ suspend and resume. Check the wedged state
> while holding the mutex so either ordering leaves interrupts disabled.
> 
> Cc: Matthew Brost <[email protected]>
> Cc: Thomas Hellström <[email protected]>
> Cc: Himal Prasad Ghimiray <[email protected]>
> Cc: Rodrigo Vivi <[email protected]>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Arvind Yadav <[email protected]>
> ---
>  drivers/gpu/drm/xe/xe_device_types.h |  4 ++++
>  drivers/gpu/drm/xe/xe_irq.c          | 26 +++++++++++++++++++++++---
>  2 files changed, 27 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_device_types.h 
> b/drivers/gpu/drm/xe/xe_device_types.h
> index 43a86564adf0..dda4d9919ca6 100644
> --- a/drivers/gpu/drm/xe/xe_device_types.h
> +++ b/drivers/gpu/drm/xe/xe_device_types.h
> @@ -6,6 +6,7 @@
>  #ifndef _XE_DEVICE_TYPES_H_
>  #define _XE_DEVICE_TYPES_H_
>  
> +#include <linux/mutex.h>
>  #include <linux/pci.h>
>  #include <linux/srcu.h>
>  
> @@ -266,6 +267,9 @@ struct xe_device {
>               /** @irq.lock: lock for processing irq's on this device */
>               spinlock_t lock;
>  
> +             /** @irq.pm_lock: Serializes IRQ suspend and resume */
> +             struct mutex pm_lock;
> +
>               /** @irq.enabled: interrupts enabled on this device */
>               atomic_t enabled;
>  
> diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
> index d314993b14a1..9cdcb16f3ca8 100644
> --- a/drivers/gpu/drm/xe/xe_irq.c
> +++ b/drivers/gpu/drm/xe/xe_irq.c
> @@ -797,8 +797,14 @@ static void irq_uninstall(void *arg)
>  
>  int xe_irq_init(struct xe_device *xe)
>  {
> +     int err;
> +
>       spin_lock_init(&xe->irq.lock);
>  
> +     err = drmm_mutex_init(&xe->drm, &xe->irq.pm_lock);
> +     if (err)
> +             return err;
> +
>       return xe_irq_msix_init(xe);
>  }
>  
> @@ -843,6 +849,8 @@ static void xe_irq_msi_synchronize_irq(struct xe_device 
> *xe)
>  
>  void xe_irq_suspend(struct xe_device *xe)
>  {
> +     mutex_lock(&xe->irq.pm_lock);
> +
>       atomic_set(&xe->irq.enabled, 0); /* no new irqs */
>  
>       /* flush irqs */
> @@ -851,6 +859,8 @@ void xe_irq_suspend(struct xe_device *xe)
>       else
>               xe_irq_msi_synchronize_irq(xe);
>       xe_irq_reset(xe); /* turn irqs off */
> +
> +     mutex_unlock(&xe->irq.pm_lock);
>  }
>  
>  void xe_irq_resume(struct xe_device *xe)
> @@ -858,10 +868,17 @@ void xe_irq_resume(struct xe_device *xe)
>       struct xe_gt *gt;
>       int id;
>  
> +     mutex_lock(&xe->irq.pm_lock);
> +
> +     if (xe_device_wedged(xe))
> +             goto out_unlock;
> +
>       /*
> -      * lock not needed:
> -      * 1. no irq will arrive before the postinstall
> -      * 2. display is not yet resumed
> +      * pm_lock serializes resume against wedge isolation.

if we are using mutex to serialize code we are doing it wrong.
worth reading:  https://blog.ffwll.ch/2022/08/locking-hierarchy.html

> +      *
> +      * irq.lock is not needed because:
> +      * 1. no IRQ arrives before postinstall;
> +      * 2. display has not been resumed yet.
>        */
>       atomic_set(&xe->irq.enabled, 1);
>       xe_irq_reset(xe);
> @@ -869,6 +886,9 @@ void xe_irq_resume(struct xe_device *xe)
>  
>       for_each_gt(gt, xe, id)
>               xe_irq_enable_hwe(gt);
> +
> +out_unlock:
> +     mutex_unlock(&xe->irq.pm_lock);
>  }
>  
>  /* MSI-X related definitions and functions below. */
> -- 
> 2.43.0
> 

Reply via email to