Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Raag Jadav <raag.jadav@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: matthew.brost@intel.com, rodrigo.vivi@intel.com,
	thomas.hellstrom@linux.intel.com, riana.tauro@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, Raag Jadav <raag.jadav@intel.com>
Subject: [PATCH v10 08/10] drm/xe: Introduce temporary device wedging
Date: Fri, 21 Aug 2026 16:53:30 +0530	[thread overview]
Message-ID: <20260821112436.545405-9-raag.jadav@intel.com> (raw)
In-Reply-To: <20260821112436.545405-1-raag.jadav@intel.com>

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)
---
 drivers/gpu/drm/xe/xe_device.c       | 106 ++++++++++++++++++++-------
 drivers/gpu/drm/xe/xe_device.h       |   8 +-
 drivers/gpu/drm/xe/xe_device_types.h |   8 +-
 drivers/gpu/drm/xe/xe_pci.c          |   1 +
 drivers/gpu/drm/xe/xe_pci_error.c    |  10 ++-
 5 files changed, 96 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 0ffed5d1cadb..8317bb9b81b4 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -607,6 +607,10 @@ int xe_device_init_early(struct xe_device *xe)
 	if (err)
 		return err;
 
+	err = drmm_mutex_init(&xe->drm, &xe->wedged.lock);
+	if (err)
+		return err;
+
 	err = xe_pm_init_early(xe);
 	if (err)
 		return err;
@@ -930,8 +934,10 @@ static void xe_device_wedged_fini(struct drm_device *drm, void *arg)
 {
 	struct xe_device *xe = arg;
 
-	if (atomic_read(&xe->wedged.flag))
-		xe_pm_runtime_put(xe);
+	if (xe->wedged.perm)
+		xe_device_wedged_put(xe);
+
+	xe_assert(xe, !xe_device_wedged(xe));
 }
 
 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE
@@ -1433,6 +1439,50 @@ u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address)
  *   firmware and restore device to normal operation.
  */
 
+/**
+ * xe_device_wedged_get() - Acquire wedged reference
+ * @xe: xe device instance
+ *
+ * Get runtime PM reference and block critical path execution.
+ */
+void xe_device_wedged_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_device_wedged_put() - Relinquish wedged reference
+ * @xe: xe device instance
+ *
+ * Restore critical path execution and put runtime PM reference.
+ */
+void xe_device_wedged_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_device_wedged() - Check for wedged device
+ * @xe: xe device instance
+ *
+ * Returns: %true if device is wedged, %false otherwise.
+ */
+bool xe_device_wedged(struct xe_device *xe)
+{
+	return atomic_read(&xe->wedged.ref);
+}
+
 /**
  * xe_device_set_wedged_method - Set wedged recovery method
  * @xe: xe device instance
@@ -1476,36 +1526,40 @@ void xe_device_declare_wedged(struct xe_device *xe)
 		return;
 	}
 
-	if (!atomic_xchg(&xe->wedged.flag, 1)) {
-		xe->needs_flr_on_fini = true;
-		xe_pm_runtime_get_noresume(xe);
+	mutex_lock(&xe->wedged.lock);
 
-		xe_log_err_fatal(xe, WEDGED, -EIO, "Device declared wedged!\n");
-		xe_err_once(xe, "IOCTLs and executions are now blocked!\n"
-			    "For recovery procedure, refer to %s\n"
-			    "Please file a _new_ bug report at %s\n",
-			    WEDGED_URL, XE_BUG_URL);
-	}
+	if (xe->wedged.perm)
+		goto out;
+
+	xe_device_wedged_get(xe);
+	xe->wedged.perm = true;
+	xe->needs_flr_on_fini = true;
+
+	xe_log_err_fatal(xe, WEDGED, -EIO, "Device declared wedged!\n");
+	xe_err_once(xe, "IOCTLs and executions are now blocked!\n"
+			"For recovery procedure, refer to %s\n"
+			"Please file a _new_ bug report at %s\n",
+			WEDGED_URL, XE_BUG_URL);
 
 	for_each_gt(gt, xe, id)
 		xe_gt_declare_wedged(gt);
 
-	if (xe_device_wedged(xe)) {
-		/*
-		 * XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET is intended for debugging
-		 * hangs, so wedge the device with 'none' recovery method and have
-		 * it available to the user for debugging.
-		 */
-		if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
-			xe_device_set_wedged_method(xe, DRM_WEDGE_RECOVERY_NONE);
-		/* If no wedge recovery method is set, use default */
-		else if (!xe->wedged.method)
-			xe_device_set_wedged_method(xe, DRM_WEDGE_RECOVERY_REBIND |
-						    DRM_WEDGE_RECOVERY_BUS_RESET);
+	/*
+	 * XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET is intended for debugging
+	 * hangs, so wedge the device with 'none' recovery method and have
+	 * it available to the user for debugging.
+	 */
+	if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
+		xe_device_set_wedged_method(xe, DRM_WEDGE_RECOVERY_NONE);
+	/* If no wedge recovery method is set, use default */
+	else if (!xe->wedged.method)
+		xe_device_set_wedged_method(xe, DRM_WEDGE_RECOVERY_REBIND |
+					    DRM_WEDGE_RECOVERY_BUS_RESET);
 
-		/* Notify userspace of wedged device */
-		drm_dev_wedged_event(&xe->drm, xe->wedged.method, NULL);
-	}
+	/* Notify userspace of wedged device */
+	drm_dev_wedged_event(&xe->drm, xe->wedged.method, NULL);
+out:
+	mutex_unlock(&xe->wedged.lock);
 }
 
 /**
diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h
index 67083915320a..8fff3fd489c7 100644
--- a/drivers/gpu/drm/xe/xe_device.h
+++ b/drivers/gpu/drm/xe/xe_device.h
@@ -209,11 +209,6 @@ bool xe_device_is_l2_flush_optimized(struct xe_device *xe);
 void xe_device_td_flush(struct xe_device *xe);
 void xe_device_l2_flush(struct xe_device *xe);
 
-static inline bool xe_device_wedged(struct xe_device *xe)
-{
-	return atomic_read(&xe->wedged.flag);
-}
-
 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE
 static inline bool xe_debug_page_size_supported(struct xe_device *xe)
 {
@@ -262,6 +257,9 @@ static inline bool xe_debug_page_size_mode_is_mixed(struct xe_device *xe)
 }
 #endif
 
+void xe_device_wedged_get(struct xe_device *xe);
+void xe_device_wedged_put(struct xe_device *xe);
+bool xe_device_wedged(struct xe_device *xe);
 void xe_device_set_wedged_method(struct xe_device *xe, unsigned long method);
 void xe_device_declare_wedged(struct xe_device *xe);
 int xe_device_validate_wedged_mode(struct xe_device *xe, unsigned int mode);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 180d450a6deb..7be3f15bf7a0 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -526,14 +526,18 @@ struct xe_device {
 
 	/** @wedged: Struct to control Wedged States and mode */
 	struct {
-		/** @wedged.flag: Xe device faced a critical error and is now blocked. */
-		atomic_t flag;
+		/** @wedged.ref: Refcount for wedged device, blocks critical path execution */
+		atomic_t ref;
 		/** @wedged.mode: Mode controlled by kernel parameter and debugfs */
 		enum xe_wedged_mode mode;
 		/** @wedged.method: Recovery method to be sent in the drm device wedged uevent */
 		unsigned long method;
 		/** @wedged.inconsistent_reset: Inconsistent reset policy state between GTs */
 		bool inconsistent_reset;
+		/** @wedged.perm: Permanently wedged, needs cleanup on fini */
+		bool perm;
+		/** @wedged.lock: Lock protecting wedged state */
+		struct mutex lock;
 	} wedged;
 
 	/** @devres_group: devres group */
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index 1e04e8ef2611..9a6c8e16a0b5 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -1390,6 +1390,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_device_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 79ce0c671549..48466d726eae 100644
--- a/drivers/gpu/drm/xe/xe_pci_error.c
+++ b/drivers/gpu/drm/xe/xe_pci_error.c
@@ -25,8 +25,10 @@ static void prepare_device_for_reset(struct pci_dev *pdev)
 	 * xe_device_wedged_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_device_wedged_get(xe);
+
+	/* TODO: We shouldn't be doing such ugly hacks, reuse FLR helpers and drop this. */
+	xe->wedged.perm = true;
 
 	xe_device_set_in_reset(xe);
 
@@ -126,7 +128,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_device_wedged_get(xe);
 
 	return PCI_ERS_RESULT_RECOVERED;
 }
@@ -137,7 +139,7 @@ static void xe_pci_error_resume(struct pci_dev *pdev)
 
 	xe_info(xe, "PCI error: resume\n");
 
-	atomic_set(&xe->wedged.flag, 0);
+	xe_device_wedged_put(xe);
 }
 
 const struct pci_error_handlers xe_pci_error_handlers = {
-- 
2.43.0


  parent reply	other threads:[~2026-08-21 11:25 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 11:23 [PATCH v10 00/10] Introduce Xe PCIe FLR Raag Jadav
2026-08-21 11:23 ` [PATCH v10 01/10] drm/xe/uc_fw: Allow re-initializing firmware Raag Jadav
2026-08-21 11:41   ` sashiko-bot
2026-08-21 11:23 ` [PATCH v10 02/10] drm/xe/guc_submit: Introduce guc_exec_queue_reinit_kernel() Raag Jadav
2026-08-21 11:52   ` sashiko-bot
2026-08-21 11:23 ` [PATCH v10 03/10] drm/xe/gt: Introduce FLR helpers Raag Jadav
2026-08-21 11:23 ` [PATCH v10 04/10] drm/xe/bo_evict: Introduce xe_bo_restore_map() Raag Jadav
2026-08-21 11:23 ` [PATCH v10 05/10] drm/xe/exec_queue: Introduce xe_exec_queue_reinit() Raag Jadav
2026-08-21 11:43   ` sashiko-bot
2026-08-21 11:23 ` [PATCH v10 06/10] drm/xe/migrate: Introduce xe_migrate_reinit() Raag Jadav
2026-08-21 11:39   ` sashiko-bot
2026-08-21 11:23 ` [PATCH v10 07/10] drm/xe/pm: Introduce xe_device_suspend/resume() Raag Jadav
2026-08-21 11:43   ` sashiko-bot
2026-08-21 11:23 ` Raag Jadav [this message]
2026-08-21 11:37   ` [PATCH v10 08/10] drm/xe: Introduce temporary device wedging sashiko-bot
2026-08-21 11:23 ` [PATCH v10 09/10] drm/xe/pci: Introduce PCIe Function Level Reset Raag Jadav
2026-08-21 11:39   ` sashiko-bot
2026-08-21 11:23 ` [PATCH v10 10/10] drm/xe/doc: Wire up PCI Error Handling Raag Jadav
2026-08-21 11:31 ` ✗ CI.checkpatch: warning for Introduce Xe PCIe FLR (rev10) Patchwork
2026-08-21 11:33 ` ✓ CI.KUnit: success " Patchwork
2026-08-21 12:37 ` ✓ Xe.CI.BAT: " Patchwork
2026-08-21 14:38 ` ✓ Xe.CI.FULL: " Patchwork

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=20260821112436.545405-9-raag.jadav@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