Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Cc: simona.vetter@ffwll.ch, thomas.hellstrom@linux.intel.com,
	pstanner@redhat.com, boris.brezillon@collabora.com,
	airlied@gmail.com, ltuikov89@gmail.com, dakr@kernel.org,
	christian.koenig@amd.com, mihail.atanassov@arm.com,
	steven.price@arm.com, shashank.sharma@amd.com
Subject: [RFC PATCH 1/6] dma-resv: Add DMA_RESV_USAGE_PREEMPT
Date: Sat,  9 Nov 2024 09:29:37 -0800	[thread overview]
Message-ID: <20241109172942.482630-2-matthew.brost@intel.com> (raw)
In-Reply-To: <20241109172942.482630-1-matthew.brost@intel.com>

Add a new DMA reservation slot, which is the highest priority and used
exclusively for preemptive fences. The semantics of this slot require
that all other fences in other slots must be signaled before any fences
in the preemptive slot enable signaling. These semantics exist to avoid
deadlocks during user submissions when using DMA fences. These rules are
baked into dma-resv.

Cc: Dave Airlie <airlied@redhat.com>
Cc: Simona Vetter <simona.vetter@ffwll.ch>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
 drivers/dma-buf/dma-resv.c    | 43 +++++++++++++++++++++++------------
 drivers/dma-buf/st-dma-resv.c |  2 +-
 include/linux/dma-fence.h     |  1 +
 include/linux/dma-resv.h      | 24 ++++++++++++++-----
 4 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 5f8d010516f0..7358aa466c75 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -57,9 +57,6 @@
 DEFINE_WD_CLASS(reservation_ww_class);
 EXPORT_SYMBOL(reservation_ww_class);
 
-/* Mask for the lower fence pointer bits */
-#define DMA_RESV_LIST_MASK	0x3
-
 struct dma_resv_list {
 	struct rcu_head rcu;
 	u32 num_fences, max_fences;
@@ -71,13 +68,14 @@ static void dma_resv_list_entry(struct dma_resv_list *list, unsigned int index,
 				struct dma_resv *resv, struct dma_fence **fence,
 				enum dma_resv_usage *usage)
 {
-	long tmp;
 
-	tmp = (long)rcu_dereference_check(list->table[index],
-					  resv ? dma_resv_held(resv) : true);
-	*fence = (struct dma_fence *)(tmp & ~DMA_RESV_LIST_MASK);
+	*fence = (struct dma_fence *)rcu_dereference_check(list->table[index],
+							   resv ?
+							   dma_resv_held(resv) :
+							   true);
+
 	if (usage)
-		*usage = tmp & DMA_RESV_LIST_MASK;
+		*usage = (*fence)->usage;
 }
 
 /* Set the fence and usage flags at the specific index in the list. */
@@ -86,9 +84,8 @@ static void dma_resv_list_set(struct dma_resv_list *list,
 			      struct dma_fence *fence,
 			      enum dma_resv_usage usage)
 {
-	long tmp = ((long)fence) | usage;
-
-	RCU_INIT_POINTER(list->table[index], (struct dma_fence *)tmp);
+	fence->usage = usage;
+	RCU_INIT_POINTER(list->table[index], fence);
 }
 
 /*
@@ -527,7 +524,7 @@ int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
 
 	list = NULL;
 
-	dma_resv_iter_begin(&cursor, src, DMA_RESV_USAGE_BOOKKEEP);
+	dma_resv_iter_begin(&cursor, src, DMA_RESV_USAGE_PREEMPT);
 	dma_resv_for_each_fence_unlocked(&cursor, f) {
 
 		if (dma_resv_iter_is_restarted(&cursor)) {
@@ -680,8 +677,11 @@ long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
 	long ret = timeout ? timeout : 1;
 	struct dma_resv_iter cursor;
 	struct dma_fence *fence;
+	enum dma_resv_usage walk_usage = (usage == DMA_RESV_USAGE_PREEMPT) ?
+		DMA_RESV_USAGE_BOOKKEEP : usage;
 
-	dma_resv_iter_begin(&cursor, obj, usage);
+wait_again:
+	dma_resv_iter_begin(&cursor, obj, walk_usage);
 	dma_resv_for_each_fence_unlocked(&cursor, fence) {
 
 		ret = dma_fence_wait_timeout(fence, intr, ret);
@@ -692,6 +692,20 @@ long dma_resv_wait_timeout(struct dma_resv *obj, enum dma_resv_usage usage,
 	}
 	dma_resv_iter_end(&cursor);
 
+	/*
+	 * Now wait on preempt fences, pipeline preemption by enabling signaling
+	 * before waiting.
+	 */
+	if (walk_usage != usage) {
+		dma_resv_iter_begin(&cursor, obj, usage);
+		dma_resv_for_each_fence_unlocked(&cursor, fence)
+			dma_fence_enable_sw_signaling(fence);
+		dma_resv_iter_end(&cursor);
+
+		walk_usage = usage;
+		goto wait_again;
+	}
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dma_resv_wait_timeout);
@@ -757,7 +771,8 @@ EXPORT_SYMBOL_GPL(dma_resv_test_signaled);
  */
 void dma_resv_describe(struct dma_resv *obj, struct seq_file *seq)
 {
-	static const char *usage[] = { "kernel", "write", "read", "bookkeep" };
+	static const char *usage[] = { "kernel", "write", "read", "bookkeep",
+		"preempt" };
 	struct dma_resv_iter cursor;
 	struct dma_fence *fence;
 
diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c
index 15dbea1462ed..ddef3c99885f 100644
--- a/drivers/dma-buf/st-dma-resv.c
+++ b/drivers/dma-buf/st-dma-resv.c
@@ -306,7 +306,7 @@ int dma_resv(void)
 	int r;
 
 	spin_lock_init(&fence_lock);
-	for (usage = DMA_RESV_USAGE_KERNEL; usage <= DMA_RESV_USAGE_BOOKKEEP;
+	for (usage = DMA_RESV_USAGE_KERNEL; usage <= DMA_RESV_USAGE_PREEMPT;
 	     ++usage) {
 		r = subtests(tests, (void *)(unsigned long)usage);
 		if (r)
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index e7ad819962e3..05f3ec2adece 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -94,6 +94,7 @@ struct dma_fence {
 	unsigned long flags;
 	struct kref refcount;
 	int error;
+	u8 usage;
 };
 
 enum dma_fence_flag_bits {
diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h
index c5ab6fd9ebe8..eb40c526d570 100644
--- a/include/linux/dma-resv.h
+++ b/include/linux/dma-resv.h
@@ -55,9 +55,10 @@ struct dma_resv_list;
  * This enum describes the different use cases for a dma_resv object and
  * controls which fences are returned when queried.
  *
- * An important fact is that there is the order KERNEL<WRITE<READ<BOOKKEEP and
- * when the dma_resv object is asked for fences for one use case the fences
- * for the lower use case are returned as well.
+ * An important fact is that there is the order
+ * KERNEL<WRITE<READ<BOOKKEEP<PREEMPT and when the dma_resv object is asked for
+ * fences for one use case the fences for the lower use case are returned as
+ * well.
  *
  * For example when asking for WRITE fences then the KERNEL fences are returned
  * as well. Similar when asked for READ fences then both WRITE and KERNEL
@@ -105,15 +106,26 @@ enum dma_resv_usage {
 	 * This should be used by submissions which don't want to participate in
 	 * any implicit synchronization.
 	 *
-	 * The most common cases are preemption fences, page table updates, TLB
-	 * flushes as well as explicitly synced user submissions.
+	 * The most common cases are page table updates, TLB flushes as well as
+	 * explicitly synced user submissions.
 	 *
 	 * Explicitly synced user submissions can be promoted to
 	 * DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE as needed using
 	 * dma_buf_import_sync_file() when implicit synchronization should
 	 * become necessary after initial adding of the fence.
 	 */
-	DMA_RESV_USAGE_BOOKKEEP
+	DMA_RESV_USAGE_BOOKKEEP,
+
+	/**
+	 * @DMA_RESV_USAGE_PREEMPT: Preempt.
+	 *
+	 * This kernel-owned slot is to install preempt fences. The semantics
+	 * require that enabling signaling on a preemption fence (and thus
+	 * preempting device execution) only occurs once all other fences in the
+	 * reservation are signaled. These rules are enforced by dma-resv to
+	 * ensure correct usage.
+	 */
+	DMA_RESV_USAGE_PREEMPT,
 };
 
 /**
-- 
2.34.1


  reply	other threads:[~2024-11-09 17:29 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-09 17:29 [RFC PATCH 0/6] Common preempt fences and semantics Matthew Brost
2024-11-09 17:29 ` Matthew Brost [this message]
2024-11-09 17:29 ` [RFC PATCH 2/6] drm/sched: Teach scheduler about DMA_RESV_USAGE_PREEMPT Matthew Brost
2024-11-12  9:06   ` Philipp Stanner
2024-11-12 20:08     ` Matthew Brost
2024-11-13 11:03       ` Philipp Stanner
2024-11-09 17:29 ` [RFC PATCH 3/6] dma-fence: Add dma_fence_preempt base class Matthew Brost
2024-11-09 17:29 ` [RFC PATCH 4/6] drm/sched: Teach scheduler about dma_fence_prempt type Matthew Brost
2024-11-09 17:29 ` [RFC PATCH 5/6] drm/xe: Use DMA_RESV_USAGE_PREEMPT for preempt fences Matthew Brost
2024-11-09 17:29 ` [RFC PATCH 6/6] drm/xe: Use dma_fence_preempt base class Matthew Brost
2024-11-09 17:35 ` ✓ CI.Patch_applied: success for Common preempt fences and semantics Patchwork
2024-11-09 17:35 ` ✗ CI.checkpatch: warning " Patchwork
2024-11-09 17:36 ` ✓ CI.KUnit: success " Patchwork
2024-11-09 17:48 ` ✓ CI.Build: " Patchwork
2024-11-09 17:50 ` ✓ CI.Hooks: " Patchwork
2024-11-09 17:51 ` ✗ CI.checksparse: warning " Patchwork
2024-11-09 18:16 ` ✓ CI.BAT: success " Patchwork
2024-11-10  8:13 ` ✗ CI.FULL: failure " Patchwork
2024-11-11 13:42 ` [RFC PATCH 0/6] " Christian König
2024-11-12  3:29   ` Matthew Brost
2024-11-12 11:09     ` Christian König
2024-11-13  2:27       ` Matthew Brost
2024-11-13  2:30         ` Matthew Brost
2024-11-13  9:02           ` Christian König
2024-11-13 15:34             ` Matthew Brost
2024-11-14  8:38               ` Christian König
2024-11-15 19:38                 ` Matthew Brost

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=20241109172942.482630-2-matthew.brost@intel.com \
    --to=matthew.brost@intel.com \
    --cc=airlied@gmail.com \
    --cc=boris.brezillon@collabora.com \
    --cc=christian.koenig@amd.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=ltuikov89@gmail.com \
    --cc=mihail.atanassov@arm.com \
    --cc=pstanner@redhat.com \
    --cc=shashank.sharma@amd.com \
    --cc=simona.vetter@ffwll.ch \
    --cc=steven.price@arm.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