From: Arvind Yadav <arvind.yadav@intel.com>
To: intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Cc: matthew.brost@intel.com, himal.prasad.ghimiray@intel.com,
thomas.hellstrom@linux.intel.com, rodrigo.vivi@intel.com
Subject: [PATCH 05/13] drm/xe: Send wedged notification from a worker
Date: Thu, 27 Aug 2026 15:47:53 +0530 [thread overview]
Message-ID: <20260827101801.1247654-6-arvind.yadav@intel.com> (raw)
In-Reply-To: <20260827101801.1247654-1-arvind.yadav@intel.com>
Move the wedged event to a device worker. This provides a sleepable
context for later isolation work and allows it to complete before
userspace is notified.
Keep one-time wedge bookkeeping on the first transition, but rescan the
GT state on later declarations because the recovery method may change.
For example, survivability handling can add VENDOR recovery after an
earlier REBIND notification.
Track the last reported method and resample it after each event so an
update is not lost when the worker is already running.
Drain the worker before probe cleanup, remove, shutdown and IRQ teardown
to prevent it from racing device teardown.
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 77 +++++++++++++++++++++++-----
drivers/gpu/drm/xe/xe_device_types.h | 4 ++
2 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index a92e90acdf0d..ffbaf85eaab1 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -83,6 +83,8 @@
#include <generated/xe_device_wa_oob.h>
#include <generated/xe_wa_oob.h>
+static void xe_device_wedged_work(struct work_struct *work);
+
static int xe_file_open(struct drm_device *dev, struct drm_file *file)
{
struct xe_device *xe = to_xe_device(dev);
@@ -535,6 +537,9 @@ int xe_device_init_early(struct xe_device *xe)
{
int err;
+ INIT_WORK(&xe->wedged.work, xe_device_wedged_work);
+ xe->wedged.reported_method = ~0UL;
+
err = ttm_device_init(&xe->ttm, &xe_ttm_funcs, xe->drm.dev,
xe->drm.anon_inode->i_mapping,
xe->drm.vma_offset_manager,
@@ -953,6 +958,35 @@ static int xe_debug_page_size_alloc_ctrl_init(struct xe_device *xe)
}
#endif
+static void xe_device_wedged_work(struct work_struct *work)
+{
+ struct xe_device *xe =
+ container_of(work, struct xe_device, wedged.work);
+ unsigned long method;
+
+ /* Report at most one recovery method per worker invocation. */
+ method = READ_ONCE(xe->wedged.method);
+ if (method != READ_ONCE(xe->wedged.reported_method)) {
+ drm_dev_wedged_event(&xe->drm, method, NULL);
+ WRITE_ONCE(xe->wedged.reported_method, method);
+ }
+
+ /*
+ * Queue another pass if the method changed while the event was sent.
+ * This preserves the update without keeping this worker in a loop.
+ */
+ if (READ_ONCE(xe->wedged.method) !=
+ READ_ONCE(xe->wedged.reported_method))
+ queue_work(xe->unordered_wq, &xe->wedged.work);
+}
+
+static void xe_device_wedged_disable(void *arg)
+{
+ struct xe_device *xe = arg;
+
+ disable_work_sync(&xe->wedged.work);
+}
+
int xe_device_probe(struct xe_device *xe)
{
struct xe_tile *tile;
@@ -1061,6 +1095,12 @@ int xe_device_probe(struct xe_device *xe)
if (err)
return err;
+ /* Drain wedge work before irq_uninstall() during devres unwind. */
+ err = devm_add_action_or_reset(xe->drm.dev,
+ xe_device_wedged_disable, xe);
+ if (err)
+ return err;
+
for_each_gt(gt, xe, id) {
err = xe_gt_init(gt);
if (err)
@@ -1166,6 +1206,7 @@ int xe_device_probe(struct xe_device *xe)
return 0;
err_unregister_display:
+ xe_device_wedged_disable(xe);
xe_display_unregister(xe);
drm_dev_unregister(&xe->drm);
@@ -1174,6 +1215,8 @@ int xe_device_probe(struct xe_device *xe)
void xe_device_remove(struct xe_device *xe)
{
+ xe_device_wedged_disable(xe);
+
xe_display_unregister(xe);
drm_dev_unplug(&xe->drm);
@@ -1188,6 +1231,8 @@ void xe_device_shutdown(struct xe_device *xe)
drm_dbg(&xe->drm, "Shutting down device\n");
+ xe_device_wedged_disable(xe);
+
xe_display_shutdown(xe);
xe_irq_suspend(xe);
@@ -1440,7 +1485,7 @@ u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address)
*/
void xe_device_set_wedged_method(struct xe_device *xe, unsigned long method)
{
- xe->wedged.method = method;
+ WRITE_ONCE(xe->wedged.method, method);
}
#define WEDGED_URL "https://docs.kernel.org/gpu/drm-uapi.html#device-wedging"
@@ -1467,6 +1512,7 @@ void xe_device_set_wedged_method(struct xe_device *xe, unsigned long method)
void xe_device_declare_wedged(struct xe_device *xe)
{
struct xe_gt *gt;
+ bool first;
u8 id;
if (xe->wedged.mode == XE_WEDGED_MODE_NEVER) {
@@ -1474,7 +1520,8 @@ void xe_device_declare_wedged(struct xe_device *xe)
return;
}
- if (!atomic_xchg(&xe->wedged.flag, 1)) {
+ first = !atomic_xchg(&xe->wedged.flag, 1);
+ if (first) {
xe->needs_flr_on_fini = true;
xe_pm_runtime_get_noresume(xe);
@@ -1483,12 +1530,7 @@ void xe_device_declare_wedged(struct xe_device *xe)
"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
@@ -1496,14 +1538,21 @@ void xe_device_declare_wedged(struct xe_device *xe)
*/
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);
}
+
+ /* Re-scan GT submission state on every declaration. */
+ for_each_gt(gt, xe, id)
+ xe_gt_declare_wedged(gt);
+
+ /* If no wedge recovery method is set, use default */
+ if (!READ_ONCE(xe->wedged.method))
+ xe_device_set_wedged_method(xe, DRM_WEDGE_RECOVERY_REBIND |
+ DRM_WEDGE_RECOVERY_BUS_RESET);
+
+ if (first ||
+ READ_ONCE(xe->wedged.method) !=
+ READ_ONCE(xe->wedged.reported_method))
+ queue_work(xe->unordered_wq, &xe->wedged.work);
}
/**
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 180d450a6deb..382a2b470647 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -534,6 +534,10 @@ struct xe_device {
unsigned long method;
/** @wedged.inconsistent_reset: Inconsistent reset policy state between GTs */
bool inconsistent_reset;
+ /** @wedged.work: Runs sleepable wedge handling */
+ struct work_struct work;
+ /** @wedged.reported_method: Last recovery method reported to userspace */
+ unsigned long reported_method;
} wedged;
/** @devres_group: devres group */
--
2.43.0
next prev parent reply other threads:[~2026-08-27 10:18 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 10:17 [PATCH 00/13] drm/xe: Isolate wedged devices from hardware access Arvind Yadav
2026-08-27 10:17 ` [PATCH 01/13] drm/xe/irq: Always free requested IRQs on uninstall Arvind Yadav
2026-08-27 10:39 ` Ghimiray, Himal Prasad
2026-08-27 10:17 ` [PATCH 02/13] drm/xe: Separate AER reset state from device wedging Arvind Yadav
2026-08-27 10:36 ` sashiko-bot
2026-08-27 21:55 ` Andi Shyti
2026-08-28 3:32 ` Yadav, Arvind
2026-08-28 11:36 ` [PATCH 2/13] " Raag Jadav
2026-08-27 10:17 ` [PATCH 03/13] drm/xe: Drop queued page faults when device I/O is blocked Arvind Yadav
2026-08-27 10:17 ` [PATCH 04/13] drm/xe: Stop VM work " Arvind Yadav
2026-08-27 10:17 ` Arvind Yadav [this message]
2026-08-27 22:12 ` [PATCH 05/13] drm/xe: Send wedged notification from a worker Andi Shyti
2026-08-28 3:39 ` Yadav, Arvind
2026-08-27 10:17 ` [PATCH 06/13] drm/xe: Reuse one dummy page per BO after wedge Arvind Yadav
2026-08-27 10:30 ` sashiko-bot
2026-08-27 10:17 ` [PATCH 07/13] drm/xe: Invalidate existing VRAM mappings on wedge Arvind Yadav
2026-08-27 10:17 ` [PATCH 08/13] drm/xe/irq: Serialize IRQ suspend and resume Arvind Yadav
2026-08-27 10:17 ` [PATCH 09/13] drm/xe: Isolate a wedged device before notifying userspace Arvind Yadav
2026-08-27 10:35 ` sashiko-bot
2026-08-27 10:17 ` [PATCH 10/13] drm/xe/ttm: Reject VRAM allocations on wedged devices Arvind Yadav
2026-08-27 10:17 ` [PATCH 11/13] drm/xe/guc: Skip timeout recovery on a wedged device Arvind Yadav
2026-08-27 10:18 ` [PATCH 12/13] drm/xe: Skip PM notifier preparation for wedged devices Arvind Yadav
2026-08-27 10:18 ` [PATCH 13/13] drm/xe: Block BO VM access when device I/O is unavailable Arvind Yadav
2026-08-27 10:30 ` sashiko-bot
2026-08-27 10:24 ` ✗ CI.checkpatch: warning for drm/xe: Isolate wedged devices from hardware access Patchwork
2026-08-27 10:26 ` ✓ CI.KUnit: success " Patchwork
2026-08-27 11:03 ` ✓ Xe.CI.BAT: " Patchwork
2026-08-27 12:16 ` ✓ 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=20260827101801.1247654-6-arvind.yadav@intel.com \
--to=arvind.yadav@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=himal.prasad.ghimiray@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=matthew.brost@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