Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Raag Jadav <raag.jadav@intel.com>
To: "Tauro, Riana" <riana.tauro@intel.com>
Cc: intel-xe@lists.freedesktop.org, matthew.brost@intel.com,
	rodrigo.vivi@intel.com, thomas.hellstrom@linux.intel.com,
	michal.wajdeczko@intel.com, matthew.d.roper@intel.com,
	michal.winiarski@intel.com, matthew.auld@intel.com,
	dev@lankhorst.se, jani.nikula@intel.com, lukasz.laguna@intel.com,
	lukas@wunner.de, daniele.ceraolospurio@intel.com,
	badal.nilawar@intel.com
Subject: Re: [PATCH v11 08/10] drm/xe: Introduce temporary device wedging
Date: Thu, 29 Oct 2026 09:20:37 +0100	[thread overview]
Message-ID: <auMB1QJjw7RHoiwN@black.igk.intel.com> (raw)
In-Reply-To: <d535ae06-4646-4765-a5b7-7def7cfbda7b@intel.com>

On Thu, Oct 29, 2026 at 11:44:53AM +0530, Tauro, Riana wrote:
> On 26-10-2026 10:36, Raag Jadav wrote:
> > Currently, wedged state is serving a single usecase where the device is
> > permanently declared wedged, but this doesn't allow any wedged state
> > management for runtime usecases. In preparation of usecases which require
> > to facilitate temporary device wedging, convert wedged.flag to wedged.ref
> > which serves as a driver internal refcount for wedged state and blocks
> > critical path execution during device lifetime. While at it, introduce
> > wedged.perm which signifies permanent device wedging and operates
> > independent of the refcount allowing relevant cleanup action on unwind
> > path.
> > 
> > Signed-off-by: Raag Jadav<raag.jadav@intel.com>
> > ---
> >   v9: Redesign to prevent races (Sashiko)
> > v10: Spell out temporary device wedging in subject (Lukasz)
> > v11: Update GuC CT path to check against permanent wedging (Lukasz, Riana)
> >       Put wedge reference only if device is wedged during resume() (Riana)
> > ---
> >   drivers/gpu/drm/xe/xe_guc_ct.c      |  6 +--
> >   drivers/gpu/drm/xe/xe_pci.c         |  2 +
> >   drivers/gpu/drm/xe/xe_pci_error.c   | 18 +++++++--
> >   drivers/gpu/drm/xe/xe_wedge.c       | 58 +++++++++++++++++++++++++++--
> >   drivers/gpu/drm/xe/xe_wedge.h       |  5 ++-
> >   drivers/gpu/drm/xe/xe_wedge_types.h | 13 ++++++-
> >   6 files changed, 88 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c
> > index d42f0133c1eb..152fccf8f6f1 100644
> > --- a/drivers/gpu/drm/xe/xe_guc_ct.c
> > +++ b/drivers/gpu/drm/xe/xe_guc_ct.c
> > @@ -1162,7 +1162,7 @@ static int __guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action,
> >   	xe_gt_assert(gt, g2h_len || !num_g2h);
> >   	lockdep_assert_held(&ct->lock);
> > -	if (xe_wedged(ct_to_xe(ct))) {
> > +	if (xe_wedge_not_recoverable(ct_to_xe(ct))) {
> >   		ret = -ENOTRECOVERABLE;
> >   		goto out;
> >   	}
> > @@ -1591,7 +1591,7 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
> >   	if (g2h_fence.fail) {
> >   		if (g2h_fence.cancel) {
> >   			xe_gt_dbg(gt, "H2G request %#x canceled!\n", action[0]);
> > -			ret = xe_wedged(ct_to_xe(ct)) ? -ENOTRECOVERABLE : -ECANCELED;
> > +			ret = xe_wedge_not_recoverable(ct_to_xe(ct)) ? -ENOTRECOVERABLE : -ECANCELED;
> >   			goto unlock;
> >   		}
> >   		xe_gt_err(gt, "H2G request %#x failed: error %#x hint %#x\n",
> > @@ -1936,7 +1936,7 @@ static int g2h_read(struct xe_guc_ct *ct, u32 *msg, bool fast_path)
> >   	lockdep_assert_held(&ct->fast_lock);
> >   	/* Keep in sync with g2h_err_is_fatal() */
> > -	if (xe_wedged(xe))
> > +	if (xe_wedge_not_recoverable(xe))
> >   		return -ENOTRECOVERABLE;
> >   	if (ct->state == XE_GUC_CT_STATE_DISABLED)
> > diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
> > index 605c452a9c33..531d38bcfd1c 100644
> > --- a/drivers/gpu/drm/xe/xe_pci.c
> > +++ b/drivers/gpu/drm/xe/xe_pci.c
> > @@ -39,6 +39,7 @@
> >   #include "xe_survivability_mode.h"
> >   #include "xe_tile.h"
> >   #include "xe_tile_printk.h"
> > +#include "xe_wedge.h"
> >   enum toggle_d3cold {
> >   	D3COLD_DISABLE,
> > @@ -1400,6 +1401,7 @@ static int xe_pci_runtime_suspend(struct device *dev)
> >   	 */
> >   	xe_assert(xe, !IS_SRIOV_VF(xe));
> >   	xe_assert(xe, !pci_num_vf(pdev));
> > +	xe_assert(xe, !xe_wedged(xe));
> >   	err = xe_pm_runtime_suspend(xe);
> >   	if (err)
> > diff --git a/drivers/gpu/drm/xe/xe_pci_error.c b/drivers/gpu/drm/xe/xe_pci_error.c
> > index 9bf0da3a3d15..cdd0af4ec139 100644
> > --- a/drivers/gpu/drm/xe/xe_pci_error.c
> > +++ b/drivers/gpu/drm/xe/xe_pci_error.c
> > @@ -26,8 +26,7 @@ static void prepare_device_for_reset(struct pci_dev *pdev)
> >   	 * xe_wedge_fini() releases runtime pm if wedged flag is set, so acquire a runtime
> >   	 * pm reference to avoid underflow.
> >   	 */
> > -	if (!atomic_xchg(&xe->wedged.flag, 1))
> > -		xe_pm_runtime_get_noresume(xe);
> > +	xe_wedge_get(xe);
> >   	xe_device_set_in_reset(xe);
> > @@ -41,10 +40,16 @@ static void prepare_device_for_reset(struct pci_dev *pdev)
> >   static pci_ers_result_t ras_action_to_pci_result(struct pci_dev *pdev, u8 action)
> >   {
> > +	struct xe_device *xe = xe_any_to_xe(pdev);
> > +
> >   	switch (action) {
> >   	case XE_RAS_RECOVERY_ACTION_RECOVERED:
> >   		return PCI_ERS_RESULT_RECOVERED;
> >   	case XE_RAS_RECOVERY_ACTION_RESET:
> > +		/* We should not be doing such ugly hacks, reuse FLR callbacks and drop this. */
> > +		if (atomic_xchg(&xe->wedged.perm, 1))
> > +			return PCI_ERS_RESULT_DISCONNECT;
> > +
> >   		prepare_device_for_reset(pdev);
> >   		return PCI_ERS_RESULT_NEED_RESET;
> >   	case XE_RAS_RECOVERY_ACTION_DISCONNECT:
> > @@ -71,6 +76,10 @@ static pci_ers_result_t xe_pci_error_detected(struct pci_dev *pdev, pci_channel_
> >   	case pci_channel_io_normal:
> >   		return PCI_ERS_RESULT_CAN_RECOVER;
> >   	case pci_channel_io_frozen:
> > +		/* We should not be doing such ugly hacks, reuse FLR callbacks and drop this. */
> > +		if (atomic_xchg(&xe->wedged.perm, 1))
> > +			return PCI_ERS_RESULT_DISCONNECT;
> > +
> >   		prepare_device_for_reset(pdev);
> >   		return PCI_ERS_RESULT_NEED_RESET;
> >   	default:
> > @@ -129,7 +138,7 @@ static pci_ers_result_t xe_pci_error_slot_reset(struct pci_dev *pdev)
> >   	xe = pdev_to_xe_device(pdev);
> >   	/* Wedge the device to prevent I/O operations till the resume callback */
> > -	atomic_set(&xe->wedged.flag, 1);
> > +	xe_wedge_get(xe);
> >   	return PCI_ERS_RESULT_RECOVERED;
> >   }
> > @@ -140,7 +149,8 @@ static void xe_pci_error_resume(struct pci_dev *pdev)
> >   	xe_info(xe, "PCI error: resume\n");
> > -	atomic_set(&xe->wedged.flag, 0);
> > +	if (xe_wedged(xe))
> > +		xe_wedge_put(xe);
> >   }
> >   const struct pci_error_handlers xe_pci_error_handlers = {
> > diff --git a/drivers/gpu/drm/xe/xe_wedge.c b/drivers/gpu/drm/xe/xe_wedge.c
> > index 2f35937c5e66..49fd9251448b 100644
> > --- a/drivers/gpu/drm/xe/xe_wedge.c
> > +++ b/drivers/gpu/drm/xe/xe_wedge.c
> > @@ -6,6 +6,7 @@
> >   #include <drm/drm_drv.h>
> >   #include <drm/drm_managed.h>
> > +#include "xe_assert.h"
> >   #include "xe_defaults.h"
> >   #include "xe_device.h"
> >   #include "xe_gt.h"
> > @@ -55,6 +56,53 @@
> >    *   firmware and restore device to normal operation.
> >    */
> > +/**
> > + * xe_wedge_get() - Acquire wedge reference
> > + * @xe: xe device instance
> > + *
> > + * Get runtime PM reference and block critical path execution.
> 
> Add a documentation that this is temporary should not be used unless
> required to temporarily block
> userspace access like resets.

I'll paste the header doc here.

> Shouldn't runtime pm be associated with permanent wedging instead of
> temporary?

No, wedged.ref is blocking a lot of critical paths and you'd probably crash
and burn in case of autosuspend.

> > + */
> > +void xe_wedge_get(struct xe_device *xe)
> > +{
> > +	int ref;
> > +
> > +	/* We should not be runtime suspending as long as critical paths are blocked */
> > +	xe_pm_runtime_get_noresume(xe);
> > +
> > +	ref = atomic_inc_return(&xe->wedged.ref);
> > +	xe_assert(xe, ref > 0);
> > +}
> > +
> > +/**
> > + * xe_wedge_put() - Relinquish wedge reference
> > + * @xe: xe device instance
> > + *
> > + * Restore critical path execution and put runtime PM reference.
> > + */
> > +void xe_wedge_put(struct xe_device *xe)
> > +{
> > +	int ref;
> > +
> > +	ref = atomic_dec_return(&xe->wedged.ref);
> > +	xe_assert(xe, ref >= 0);
> > +
> > +	xe_pm_runtime_put(xe);
> > +}
> > +
> > +/**
> > + * xe_wedge_not_recoverable() - Check for unrecoverable device
> > + * @xe: xe device instance
> > + *
> > + * Do not abuse this. Use xe_wedged() instead where possible. Only
> > + * use this as a last resort where xe_wedged() is problematic.
> > + *
> > + * Returns: %true if device is unrecoverable, %false otherwise.
> > + */
> > +bool xe_wedge_not_recoverable(struct xe_device *xe)
> 
> xe_wedged_permanent?

Sure.

Raag

> > +{
> > +	return atomic_read(&xe->wedged.perm);
> > +}
> > +
> >   static void wedge_work(struct work_struct *work)
> >   {
> >   	struct xe_device *xe = container_of(work, struct xe_device, wedged.work);
> > @@ -97,11 +145,11 @@ void xe_wedge_declare(struct xe_device *xe, unsigned long method)
> >   		return;
> >   	}
> > -	if (atomic_xchg(&xe->wedged.flag, 1))
> > +	if (atomic_xchg(&xe->wedged.perm, 1))
> >   		return;
> > +	xe_wedge_get(xe);
> >   	xe->needs_flr_on_fini = true;
> > -	xe_pm_runtime_get_noresume(xe);
> >   	xe_log_err_fatal(xe, WEDGED, -EIO, "Device declared wedged!\n");
> >   	xe_err_once(xe, "IOCTLs and executions are now blocked!\n"
> > @@ -239,8 +287,10 @@ static void xe_wedge_fini(struct drm_device *drm, void *arg)
> >   	disable_work_sync(&xe->wedged.work);
> > -	if (atomic_read(&xe->wedged.flag))
> > -		xe_pm_runtime_put(xe);
> > +	if (atomic_read(&xe->wedged.perm))
> > +		xe_wedge_put(xe);
> > +
> > +	xe_assert(xe, !xe_wedged(xe));
> >   }
> >   /**
> > diff --git a/drivers/gpu/drm/xe/xe_wedge.h b/drivers/gpu/drm/xe/xe_wedge.h
> > index 3b5499dfc30d..28f43295948e 100644
> > --- a/drivers/gpu/drm/xe/xe_wedge.h
> > +++ b/drivers/gpu/drm/xe/xe_wedge.h
> > @@ -14,11 +14,14 @@
> >   static inline bool xe_wedged(struct xe_device *xe)
> >   {
> > -	return atomic_read(&xe->wedged.flag);
> > +	return atomic_read(&xe->wedged.ref);
> >   }
> >   void xe_wedge_declare(struct xe_device *xe, unsigned long method);
> >   int xe_wedge_init(struct xe_device *xe);
> >   int xe_wedge_set_mode(struct xe_device *xe, enum xe_wedged_mode mode);
> > +void xe_wedge_get(struct xe_device *xe);
> > +void xe_wedge_put(struct xe_device *xe);
> > +bool xe_wedge_not_recoverable(struct xe_device *xe);
> >   #endif
> > diff --git a/drivers/gpu/drm/xe/xe_wedge_types.h b/drivers/gpu/drm/xe/xe_wedge_types.h
> > index e472c5fcbd26..8e87290444dd 100644
> > --- a/drivers/gpu/drm/xe/xe_wedge_types.h
> > +++ b/drivers/gpu/drm/xe/xe_wedge_types.h
> > @@ -29,8 +29,17 @@ enum xe_wedged_mode {
> >    * struct xe_wedge - Struct to control Wedged States and mode
> >    */
> >   struct xe_wedge {
> > -	/** @flag: Xe device faced a critical error and is now blocked. */
> > -	atomic_t flag;
> > +	/**
> > +	 * @ref: Refcount for wedged device, blocks critical path execution. Used for
> > +	 * driver internal usecases which require temporarily blocking user access of
> > +	 * the device during autonomous recovery, like PCIe FLR and bus reset.
> > +	 */
> > +	atomic_t ref;
> > +	/**
> > +	 * @perm: Permanently wedged device, not recoverable. Only to be set when
> > +	 * notifying userspace of wedged device through drm wedged uevent.
> > +	 */
> > +	atomic_t perm;
> >   	/** @mode: Mode controlled by kernel parameter and debugfs */
> >   	enum xe_wedged_mode mode;
> >   	/** @method: Recovery method to be sent in the drm device wedged uevent */

  reply	other threads:[~2026-10-29  8:20 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26  5:06 [PATCH v11 00/10] Introduce Xe PCIe FLR Raag Jadav
2026-10-26  5:06 ` [PATCH v11 01/10] drm/xe/uc_fw: Allow re-initializing firmware Raag Jadav
2026-10-26  5:06 ` [PATCH v11 02/10] drm/xe/guc_submit: Introduce guc_exec_queue_reinit_kernel() Raag Jadav
2026-10-26  5:06 ` [PATCH v11 03/10] drm/xe/gt: Introduce FLR helpers Raag Jadav
2026-10-26  5:06 ` [PATCH v11 04/10] drm/xe/bo_evict: Introduce xe_bo_restore_map() Raag Jadav
2026-10-26  5:06 ` [PATCH v11 05/10] drm/xe/exec_queue: Introduce xe_exec_queue_reinit() Raag Jadav
2026-10-26  5:06 ` [PATCH v11 06/10] drm/xe/migrate: Introduce xe_migrate_reinit() Raag Jadav
2026-10-26  5:06 ` [PATCH v11 07/10] drm/xe/pm: Introduce xe_device_suspend/resume() Raag Jadav
2026-10-26  5:06 ` [PATCH v11 08/10] drm/xe: Introduce temporary device wedging Raag Jadav
2026-10-29  6:14   ` Tauro, Riana
2026-10-29  8:20     ` Raag Jadav [this message]
2026-10-26  5:06 ` [PATCH v11 09/10] drm/xe/pci: Introduce PCIe Function Level Reset Raag Jadav
2026-10-29  8:40   ` Tauro, Riana
2026-10-26  5:07 ` [PATCH v11 10/10] drm/xe/doc: Wire up PCI Error Handling Raag Jadav

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=auMB1QJjw7RHoiwN@black.igk.intel.com \
    --to=raag.jadav@intel.com \
    --cc=badal.nilawar@intel.com \
    --cc=daniele.ceraolospurio@intel.com \
    --cc=dev@lankhorst.se \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    --cc=lukas@wunner.de \
    --cc=lukasz.laguna@intel.com \
    --cc=matthew.auld@intel.com \
    --cc=matthew.brost@intel.com \
    --cc=matthew.d.roper@intel.com \
    --cc=michal.wajdeczko@intel.com \
    --cc=michal.winiarski@intel.com \
    --cc=riana.tauro@intel.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=thomas.hellstrom@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox