From: Tejas Upadhyay <tejas.upadhyay@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: himal.prasad.ghimiray@intel.com, rodrigo.vivi@intel.com,
michal.wajdeczko@intel.com,
"Tejas Upadhyay" <tejas.upadhyay@intel.com>,
"José Roberto de Souza" <jose.souza@intel.com>,
"Michal Mrozek" <michal.mrozek@intel.com>
Subject: [PATCH V18 13/14] drm/xe/uapi: Expose ban reason in EXEC_QUEUE_GET_PROPERTY_BAN
Date: Wed, 26 Aug 2026 19:21:48 +0530 [thread overview]
Message-ID: <20260826135136.204044-29-tejas.upadhyay@intel.com> (raw)
In-Reply-To: <20260826135136.204044-16-tejas.upadhyay@intel.com>
Extend DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN to return a bitmask indicating
the reason for the ban, rather than a simple boolean. This allows
userspace to distinguish between different ban causes:
- DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG (bit 0): exec queue was banned
due to a GPU hang or job timeout detected by the TDR.
- DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE (bit 1): exec queue was
banned because a VRAM page backing its resources was taken offline.
The ban_reason field is added to struct xe_exec_queue and set at the
point where the ban is triggered:
- In guc_exec_queue_timedout_job() for GPU hang.
- In xe_ttm_vram_purge_page() for memory page offline, before calling
xe_exec_queue_kill() or xe_vm_kill().
The reset_status op is updated to return u64 with the reason bitmask.
When a queue is banned but no explicit reason was recorded (e.g., from a
generic CAT error), it defaults to GPU_HANG for backward compatibility.
A value of 0 means the exec queue is not banned.
v4(Sashiko):
- Add ban reason for non-LR exec queues
- Add TODO for multiqueue
v3(Rodrigo):
- Add doc in xe_drm.h
v2(Sashiko):
- Use atomic_t for ban_reason to fix concurrent updates from TDR and
page-offline
- Guard GPU_HANG bit with !exec_queue_killed to avoid masking
page-offline reason
- Clear ban_reason on queue recovery (clear_exec_queue_banned path)
- Use atomic_read in guc_exec_queue_reset_status for lockless read
Assisted-by: Copilot:claude-opus-4.6
Acked-by: José Roberto de Souza <jose.souza@intel.com>
Acked-by: Michal Mrozek <michal.mrozek@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
---
drivers/gpu/drm/xe/xe_exec_queue_types.h | 7 +++--
drivers/gpu/drm/xe/xe_execlist.c | 4 +--
drivers/gpu/drm/xe/xe_guc_submit.c | 36 ++++++++++++++++++++----
drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 19 +++++++++++++
include/uapi/drm/xe_drm.h | 18 +++++++++++-
5 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h
index 95f75d61a647..836f88fc0faa 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h
@@ -154,6 +154,9 @@ struct xe_exec_queue {
*/
unsigned long flags;
+ /** @ban_reason: Bitmask of ban reasons (DRM_XE_EXEC_QUEUE_BAN_REASON_*) */
+ atomic_t ban_reason;
+
union {
/** @multi_gt_list: list head for VM bind engines if multi-GT */
struct list_head multi_gt_list;
@@ -348,8 +351,8 @@ struct xe_exec_queue_ops {
* signalled when this function is called.
*/
void (*resume)(struct xe_exec_queue *q);
- /** @reset_status: check exec queue reset status */
- bool (*reset_status)(struct xe_exec_queue *q);
+ /** @reset_status: check exec queue ban status, returns ban reason bitmask */
+ u64 (*reset_status)(struct xe_exec_queue *q);
};
#endif
diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c
index 0d0db66c6ea2..a36db39dcda8 100644
--- a/drivers/gpu/drm/xe/xe_execlist.c
+++ b/drivers/gpu/drm/xe/xe_execlist.c
@@ -453,10 +453,10 @@ static void execlist_exec_queue_resume(struct xe_exec_queue *q)
/* NIY */
}
-static bool execlist_exec_queue_reset_status(struct xe_exec_queue *q)
+static u64 execlist_exec_queue_reset_status(struct xe_exec_queue *q)
{
/* NIY */
- return false;
+ return 0;
}
static const struct xe_exec_queue_ops execlist_exec_queue_ops = {
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 99d8c807ff05..0a6e2b81b5a5 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -6,6 +6,7 @@
#include "xe_guc_submit.h"
#include <linux/bitfield.h>
+#include <uapi/drm/xe_drm.h>
#include <linux/bitmap.h>
#include <linux/circ_buf.h>
#include <linux/dma-fence-array.h>
@@ -1599,6 +1600,12 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
else
wedged = xe_device_wedged(xe);
+ /*
+ * Only tag as GPU hang if this is the original timeout, not a
+ * consequence of a prior kill (e.g., page-offline).
+ */
+ if (!exec_queue_killed(q))
+ atomic_or(DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG, &q->ban_reason);
set_exec_queue_banned(q);
/* Kick job / queue off hardware */
@@ -1682,6 +1689,9 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
if (timeout_needs_gt_reset(q, job, skip_timeout_check)) {
if (!xe_sched_invalidate_job(job, 2)) {
clear_exec_queue_banned(q);
+ /* protect concurrent page offline reasons */
+ atomic_andnot(DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG,
+ &q->ban_reason);
xe_gt_reset_async(q->gt);
goto rearm;
}
@@ -2580,13 +2590,29 @@ static void guc_exec_queue_multi_queue_drop_suspend(struct xe_exec_queue *q)
}
}
-static bool guc_exec_queue_reset_status(struct xe_exec_queue *q)
+static u64 guc_exec_queue_reset_status(struct xe_exec_queue *q)
{
- if (xe_exec_queue_is_multi_queue_secondary(q) &&
- guc_exec_queue_reset_status(xe_exec_queue_multi_queue_primary(q)))
- return true;
+ /* TODO: In case of multiqueue, if a secondary queue is banned due to
+ * page offlining, checking only the primary queue's GuC reset status
+ * may mask the true reason or race with it.
+ */
+ if (xe_exec_queue_is_multi_queue_secondary(q)) {
+ u64 status = guc_exec_queue_reset_status(xe_exec_queue_multi_queue_primary(q));
- return exec_queue_reset(q) || exec_queue_killed_or_banned_or_wedged(q);
+ if (status)
+ return status;
+ }
+
+ if (exec_queue_reset(q) || exec_queue_killed_or_banned_or_wedged(q)) {
+ u64 reason = atomic_read_acquire(&q->ban_reason);
+
+ /* If no specific reason was recorded, default to GPU hang */
+ if (!reason)
+ reason = DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG;
+ return reason;
+ }
+
+ return 0;
}
/*
diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
index af9e1fa868d7..8f583f1631bf 100644
--- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
@@ -10,6 +10,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_drv.h>
#include <drm/drm_buddy.h>
+#include <uapi/drm/xe_drm.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_range_manager.h>
@@ -582,6 +583,7 @@ u64 xe_ttm_vram_get_avail(struct ttm_resource_manager *man)
static int xe_ttm_vram_purge_page(struct xe_device *xe, struct xe_bo *bo)
{
+ u32 q_flag = DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE;
struct ttm_operation_ctx ctx = {};
struct xe_exec_queue *q_to_put = NULL;
struct xe_exec_queue *q = NULL;
@@ -596,7 +598,22 @@ static int xe_ttm_vram_purge_page(struct xe_device *xe, struct xe_bo *bo)
xe_bo_unlock(bo);
/* Ban VM if BO is PPGTT */
if (vm && (flags & XE_BO_FLAG_PAGETABLE)) {
+ struct xe_exec_queue *eq;
+ int id;
+
down_write(&vm->lock);
+ if (xe->info.has_ctx_tlb_inval) {
+ down_read(&vm->exec_queues.lock);
+ for (id = 0; id < ARRAY_SIZE(vm->exec_queues.list); id++)
+ list_for_each_entry(eq, &vm->exec_queues.list[id],
+ vm_exec_queue_link)
+ atomic_or(q_flag, &eq->ban_reason);
+ up_read(&vm->exec_queues.lock);
+ } else {
+ list_for_each_entry(eq, &vm->preempt.exec_queues, lr.link)
+ atomic_or(q_flag, &eq->ban_reason);
+ }
+ smp_wmb(); /* Force all queue bits to be visible before killing the VM */
xe_vm_kill(vm, true);
up_write(&vm->lock);
}
@@ -608,6 +625,8 @@ static int xe_ttm_vram_purge_page(struct xe_device *xe, struct xe_bo *bo)
/* Ban exec queue if BO is lrc */
if (q && xe_exec_queue_get_unless_zero(q)) {
/* ban queue */
+ atomic_or(q_flag, &q->ban_reason);
+ smp_wmb(); /* Force bit change to finish before state change triggers */
q_to_put = q;
}
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 509202a7b13e..ee4a921b2e6e 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1491,6 +1491,12 @@ struct drm_xe_exec_queue_destroy {
*
* The @property can be:
* - %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, @value is a bitmask of ban reasons:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * A @value of 0 means the exec queue is not banned.
*/
struct drm_xe_exec_queue_get_property {
/** @extensions: Pointer to the first extension struct, if any */
@@ -1503,7 +1509,17 @@ struct drm_xe_exec_queue_get_property {
/** @property: property to get */
__u32 property;
- /** @value: property value */
+ /**
+ * @value: property value
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, this is a bitmask of:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * Value of 0 means the exec queue is not banned.
+ */
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG (1 << 0)
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE (1 << 1)
__u64 value;
/** @reserved: Reserved */
--
2.52.0
next prev parent reply other threads:[~2026-08-26 13:52 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 13:51 [PATCH V18 00/14] Add memory page offlining support Tejas Upadhyay
2026-08-26 13:51 ` [PATCH V18 01/14] drm/xe: Link VRAM object with gpu buddy Tejas Upadhyay
2026-08-26 22:31 ` Andi Shyti
2026-08-26 13:51 ` [PATCH V18 02/14] drm/xe: Link LRC BO and its execution Queue Tejas Upadhyay
2026-08-26 22:34 ` Andi Shyti
2026-08-26 13:51 ` [PATCH V18 03/14] drm/xe: Extend BO purge to handle vram pages as well Tejas Upadhyay
2026-08-26 14:07 ` sashiko-bot
2026-08-26 22:42 ` Andi Shyti
2026-08-27 6:17 ` Upadhyay, Tejas
2026-08-27 14:40 ` Andi Shyti
2026-08-27 14:48 ` Upadhyay, Tejas
2026-08-28 5:25 ` Upadhyay, Tejas
2026-08-28 7:39 ` Andi Shyti
2026-08-28 17:29 ` Upadhyay, Tejas
2026-08-26 13:51 ` [PATCH V18 04/14] drm/xe/bo: Make xe_bo_is_user() public Tejas Upadhyay
2026-08-26 22:44 ` Andi Shyti
2026-08-26 13:51 ` [PATCH V18 05/14] drm/xe: Guard teardown paths against purged BOs Tejas Upadhyay
2026-08-26 14:12 ` sashiko-bot
2026-08-27 6:08 ` Ghimiray, Himal Prasad
2026-08-27 8:27 ` Upadhyay, Tejas
2026-08-26 13:51 ` [PATCH V18 06/14] drm/xe/vram: Extract buddy alloc and free helpers Tejas Upadhyay
2026-08-26 22:50 ` Andi Shyti
2026-08-26 13:51 ` [PATCH V18 07/14] drm/xe/vram: Add page offline data structures and lifecycle Tejas Upadhyay
2026-08-26 23:09 ` Andi Shyti
2026-08-27 6:19 ` Ghimiray, Himal Prasad
2026-08-26 13:51 ` [PATCH V18 08/14] drm/xe/vram: Add VRAM page offline fault handler Tejas Upadhyay
2026-08-26 14:05 ` sashiko-bot
2026-08-26 13:51 ` [PATCH V18 09/14] drm/xe/configfs: Add bad_page_reservation attribute Tejas Upadhyay
2026-08-27 6:42 ` Ghimiray, Himal Prasad
2026-08-27 15:00 ` Michal Wajdeczko
2026-08-28 17:48 ` Upadhyay, Tejas
2026-08-26 13:51 ` [PATCH V18 10/14] drm/xe/ras: Cache bad_page_reservation policy at init Tejas Upadhyay
2026-08-26 14:11 ` sashiko-bot
2026-08-27 6:45 ` Ghimiray, Himal Prasad
2026-08-26 13:51 ` [PATCH V18 11/14] drm/xe/vram: Check bad_page_reservation policy in fault handler Tejas Upadhyay
2026-08-26 14:08 ` sashiko-bot
2026-08-27 6:46 ` Ghimiray, Himal Prasad
2026-08-27 15:04 ` Michal Wajdeczko
2026-08-26 13:51 ` [PATCH V18 12/14] drm/xe: Expose bad VRAM pages via debugfs Tejas Upadhyay
2026-08-26 14:13 ` sashiko-bot
2026-08-27 15:16 ` Michal Wajdeczko
2026-08-28 19:06 ` Upadhyay, Tejas
2026-08-28 15:04 ` Rodrigo Vivi
2026-08-26 13:51 ` Tejas Upadhyay [this message]
2026-08-26 14:20 ` [PATCH V18 13/14] drm/xe/uapi: Expose ban reason in EXEC_QUEUE_GET_PROPERTY_BAN sashiko-bot
2026-08-27 18:26 ` Andi Shyti
2026-08-28 5:31 ` Upadhyay, Tejas
2026-08-26 13:51 ` [PATCH V18 14/14] drm/xe: Add fault-inject based VRAM page offline injection Tejas Upadhyay
2026-08-27 7:10 ` Ghimiray, Himal Prasad
2026-08-27 8:23 ` Upadhyay, Tejas
2026-08-26 14:37 ` ✗ CI.checkpatch: warning for Add memory page offlining support (rev21) Patchwork
2026-08-26 14:39 ` ✓ CI.KUnit: success " Patchwork
2026-08-26 15:21 ` ✓ Xe.CI.BAT: " Patchwork
2026-08-26 19:01 ` ✓ 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=20260826135136.204044-29-tejas.upadhyay@intel.com \
--to=tejas.upadhyay@intel.com \
--cc=himal.prasad.ghimiray@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=jose.souza@intel.com \
--cc=michal.mrozek@intel.com \
--cc=michal.wajdeczko@intel.com \
--cc=rodrigo.vivi@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