All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejas Upadhyay <tejas.upadhyay@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: himal.prasad.ghimiray@intel.com, rodrigo.vivi@intel.com,
	Matthew Brost <matthew.brost@intel.com>,
	Tejas Upadhyay <tejas.upadhyay@intel.com>,
	Andi Shyti <andi.shyti@linux.intel.com>
Subject: [PATCH V20 02/15] drm/xe: Link LRC BO and its execution queue with safe lifetime rules
Date: Wed,  2 Sep 2026 20:23:45 +0530	[thread overview]
Message-ID: <20260902145343.465686-19-tejas.upadhyay@intel.com> (raw)
In-Reply-To: <20260902145343.465686-17-tejas.upadhyay@intel.com>

Introduce an execution queue back-pointer (`q`) within `struct xe_bo`, primarily
for Logical Ring Context (LRC) Buffer Objects. This back-pointer allows the
driver to identify and execute targeted corrective actions on a specific queue
if its associated LRC BO encounters errors like memory corruption or eviction.

Because this back-pointer takes no reference on its target execution queue, strict
lifetime and serialization rules are implemented to prevent concurrent readers
from encountering use-after-free or dangling pointer bugs:

- Encapsulate tracking logic inside xe_exec_queue_set_lrc_bo_backpointer() and
  xe_exec_queue_clear_lrc_bo_backpointer().

- Explicitly wrap all back-pointer writes and clears under the BO's dma_resv lock
  via xe_bo_lock(). Readers must hold this same lock across both the pointer read
  and its subsequent xe_exec_queue_get_unless_zero() call to guarantee serialization
  against teardown.

- Defer publishing the back-pointer until the very end of xe_exec_queue_create().
  This ensures that early initialization failure paths (which bypass the kref
  mechanism and immediately free the queue structure) never leak a transient pointer
  to concurrent readers.

- Clear the back-pointer at the absolute top of __xe_exec_queue_fini(). This strips
  the pointer before q->ops->fini() destroys the hardware backend, ensuring that
  any reader holding the BO lock either observes a fully functional queue or NULL.

For multi-queue engines, secondary LRC BOs safely point to the primary queue, which
is guaranteed to outlive the teardown pass due to active references held by its
secondaries.

V4 (MattB):
  - Add LRC BO's execution queue safe lifetime rules
V3 (Sashiko):
  - Use 8-byte placeholder structure compatibility for non-LRC BO cases.
  - Wrap assignments and clears securely under dma_resv locks.
V2 (Matt B):
  - Add native support handling multi-queue configuration tracking.

Co-authored-by: Copilot
Reviewed-by: Andi Shyti <andi.shyti@linux.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_bo_types.h   |  8 ++++
 drivers/gpu/drm/xe/xe_exec_queue.c | 64 ++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
index e45f24301050..0eb93052c1d5 100644
--- a/drivers/gpu/drm/xe/xe_bo_types.h
+++ b/drivers/gpu/drm/xe/xe_bo_types.h
@@ -20,6 +20,7 @@
 struct xe_device;
 struct xe_mem_pool_node;
 struct xe_vm;
+struct xe_exec_queue;
 
 #define XE_BO_MAX_PLACEMENTS	3
 
@@ -42,6 +43,13 @@ struct xe_bo {
 	u32 flags;
 	/** @vm: VM this BO is attached to, for extobj this will be NULL */
 	struct xe_vm *vm;
+	/**
+	 * @q: Queue this BO is attached to, mostly for LRC BO, NULL otherwise.
+	 * Protected by the BO dma_resv: readers must hold it across both the
+	 * read and xe_exec_queue_get_unless_zero(). The BO holds no reference
+	 * on the queue.
+	 */
+	struct xe_exec_queue *q;
 	/** @tile: Tile this BO is attached to (kernel BO only) */
 	struct xe_tile *tile;
 	/** @placements: valid placements for this BO */
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index c4213bb9c137..f3ea4807ac33 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -322,10 +322,66 @@ struct xe_lrc *xe_exec_queue_lrc(struct xe_exec_queue *q)
 	return q->lrc[0];
 }
 
+/*
+ * Publish the queue back-pointer in the LRC BOs.
+ *
+ * The BO holds no reference on the queue; the queue owns the LRCs, and
+ * therefore the BOs, instead. The back-pointer is made safe by two rules:
+ *
+ *  - It is published only once the queue is fully constructed and can no
+ *    longer be destroyed by an error path that bypasses the kref (see
+ *    xe_exec_queue_create()), so a reader that successfully takes a
+ *    reference can never be handed a queue that is freed without going
+ *    through xe_exec_queue_destroy().
+ *
+ *  - It is written and cleared under the BO dma_resv. Readers must hold
+ *    the same lock across both the read and
+ *    xe_exec_queue_get_unless_zero(), which serializes them against
+ *    xe_exec_queue_clear_lrc_bo_backpointer() below.
+ *
+ * For a multi-queue group the LRC BOs point at the primary queue, which is
+ * kept alive by the reference every secondary holds on it.
+ */
+static void xe_exec_queue_set_lrc_bo_backpointer(struct xe_exec_queue *q)
+{
+	struct xe_exec_queue *primary = xe_exec_queue_multi_queue_primary(q);
+	int i;
+
+	for (i = 0; i < q->width; ++i) {
+		struct xe_bo *bo = q->lrc[i]->bo;
+
+		xe_bo_lock(bo, false);
+		bo->q = primary;
+		xe_bo_unlock(bo);
+	}
+}
+
+/*
+ * Drop the queue back-pointer before anything belonging to the queue is
+ * torn down. This must happen before q->ops->fini(), otherwise a reader
+ * could take a reference and then operate on an already destroyed backend.
+ */
+static void xe_exec_queue_clear_lrc_bo_backpointer(struct xe_exec_queue *q)
+{
+	int i;
+
+	for (i = 0; i < q->width; ++i) {
+		struct xe_bo *bo = q->lrc[i] ? q->lrc[i]->bo : NULL;
+
+		if (!bo)
+			continue;
+
+		xe_bo_lock(bo, false);
+		bo->q = NULL;
+		xe_bo_unlock(bo);
+	}
+}
+
 static void __xe_exec_queue_fini(struct xe_exec_queue *q)
 {
 	int i;
 
+	xe_exec_queue_clear_lrc_bo_backpointer(q);
 	q->ops->fini(q);
 
 	for (i = 0; i < q->width; ++i)
@@ -450,6 +506,14 @@ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *v
 			goto err_post_init;
 	}
 
+	/*
+	 * Publish the LRC BO back-pointers last: past this point the queue can
+	 * only be destroyed through xe_exec_queue_destroy(), so a concurrent
+	 * reader that takes a reference via bo->q cannot race with the
+	 * kref-bypassing error paths below.
+	 */
+	xe_exec_queue_set_lrc_bo_backpointer(q);
+
 	return q;
 
 err_post_init:
-- 
2.52.0


  parent reply	other threads:[~2026-09-02 14:54 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02 14:53 [PATCH V20 00/15] Add memory page offlining support Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 01/15] drm/xe: Link VRAM object with gpu buddy Tejas Upadhyay
2026-09-02 14:53 ` Tejas Upadhyay [this message]
2026-09-02 14:53 ` [PATCH V20 03/15] drm/xe: Export xe_ttm_bo_purge() Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 04/15] drm/xe: Handle NULL resource and allow purging of VRAM pages Tejas Upadhyay
2026-09-02 15:28   ` sashiko-bot
2026-09-02 14:53 ` [PATCH V20 05/15] drm/xe/bo: Make xe_bo_is_user() public Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 06/15] drm/xe: Guard teardown paths against purged BOs Tejas Upadhyay
2026-09-02 15:57   ` sashiko-bot
2026-09-02 17:52     ` Upadhyay, Tejas
2026-09-02 14:53 ` [PATCH V20 07/15] drm/xe/vram: Extract buddy allocation and free helpers Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 08/15] drm/xe/vram: Add page offline data structures and lifecycle Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 09/15] drm/xe/vram: Add VRAM page offline fault handler Tejas Upadhyay
2026-09-02 16:25   ` sashiko-bot
2026-09-02 23:04     ` Matthew Brost
2026-09-03  4:22       ` Matthew Brost
2026-09-03  7:57         ` Upadhyay, Tejas
2026-09-02 14:53 ` [PATCH V20 10/15] drm/xe/configfs: Add disable_vram_page_offline attribute Tejas Upadhyay
2026-09-02 16:35   ` sashiko-bot
2026-09-02 17:56     ` Upadhyay, Tejas
2026-09-02 14:53 ` [PATCH V20 11/15] drm/xe/ras: Cache disable_vram_page_offline policy at init Tejas Upadhyay
2026-09-02 14:53 ` [PATCH V20 12/15] drm/xe/vram: Check disable_vram_page_offline policy in fault handler Tejas Upadhyay
2026-09-02 16:48   ` sashiko-bot
2026-09-02 17:57     ` Upadhyay, Tejas
2026-09-02 18:31   ` Michal Wajdeczko
2026-09-02 14:53 ` [PATCH V20 13/15] drm/xe: Expose bad VRAM pages via debugfs Tejas Upadhyay
2026-09-02 16:56   ` sashiko-bot
2026-09-02 18:00     ` Upadhyay, Tejas
2026-09-02 23:08       ` Matthew Brost
2026-09-02 18:36   ` Michal Wajdeczko
2026-09-02 14:53 ` [PATCH V20 14/15] drm/xe/uapi: Expose ban reason in EXEC_QUEUE_GET_PROPERTY_BAN Tejas Upadhyay
2026-09-02 17:10   ` sashiko-bot
2026-09-02 23:12     ` Matthew Brost
2026-09-02 14:53 ` [PATCH V20 15/15] drm/xe: Add fault-inject based VRAM page offline injection Tejas Upadhyay
2026-09-02 17:02 ` ✗ CI.checkpatch: warning for Add memory page offlining support (rev24) Patchwork
2026-09-02 17:04 ` ✓ CI.KUnit: success " Patchwork
2026-09-02 17:42 ` ✓ Xe.CI.BAT: " Patchwork
2026-09-03  6:57 ` ✓ 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=20260902145343.465686-19-tejas.upadhyay@intel.com \
    --to=tejas.upadhyay@intel.com \
    --cc=andi.shyti@linux.intel.com \
    --cc=himal.prasad.ghimiray@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.brost@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.