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 3/6] dma-fence: Add dma_fence_preempt base class
Date: Sat, 9 Nov 2024 09:29:39 -0800 [thread overview]
Message-ID: <20241109172942.482630-4-matthew.brost@intel.com> (raw)
In-Reply-To: <20241109172942.482630-1-matthew.brost@intel.com>
Add a dma_fence_preempt base class with driver ops to implement
preemption, based on the existing Xe preemptive fence implementation.
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/Makefile | 2 +-
drivers/dma-buf/dma-fence-preempt.c | 102 ++++++++++++++++++++++++++++
include/linux/dma-fence-preempt.h | 54 +++++++++++++++
3 files changed, 157 insertions(+), 1 deletion(-)
create mode 100644 drivers/dma-buf/dma-fence-preempt.c
create mode 100644 include/linux/dma-fence-preempt.h
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 70ec901edf2c..c25500bb38b5 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
- dma-fence-unwrap.o dma-resv.o
+ dma-fence-preempt.o dma-fence-unwrap.o dma-resv.o
obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
obj-$(CONFIG_DMABUF_HEAPS) += heaps/
obj-$(CONFIG_SYNC_FILE) += sync_file.o
diff --git a/drivers/dma-buf/dma-fence-preempt.c b/drivers/dma-buf/dma-fence-preempt.c
new file mode 100644
index 000000000000..e97ddd925db6
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-preempt.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <linux/dma-fence-preempt.h>
+#include <linux/dma-resv.h>
+
+static const char *
+dma_fence_preempt_get_driver_name(struct dma_fence *fence)
+{
+ return "dma_fence_preempt";
+}
+
+static const char *
+dma_fence_preempt_get_timeline_name(struct dma_fence *fence)
+{
+ return "ordered";
+}
+
+static bool dma_fence_preempt_enable_signaling(struct dma_fence *fence)
+{
+ struct dma_fence_preempt *pfence =
+ container_of(fence, typeof(*pfence), base);
+ int err;
+
+ err = pfence->ops->preempt(pfence);
+ if (err)
+ dma_fence_set_error(&pfence->base, err);
+ else
+ WARN_ON(!dma_resv_test_signaled(pfence->resv,
+ DMA_RESV_USAGE_BOOKKEEP));
+
+ dma_fence_get(fence);
+ queue_work(pfence->wq, &pfence->work);
+
+ return true;
+}
+
+static const struct dma_fence_ops preempt_fence_ops = {
+ .get_driver_name = dma_fence_preempt_get_driver_name,
+ .get_timeline_name = dma_fence_preempt_get_timeline_name,
+ .enable_signaling = dma_fence_preempt_enable_signaling,
+};
+
+static void dma_fence_preempt_work_func(struct work_struct *w)
+{
+ bool cookie = dma_fence_begin_signalling();
+ struct dma_fence_preempt *pfence =
+ container_of(w, typeof(*pfence), work);
+ int err = pfence->base.error;
+
+ if (!err) {
+ err = pfence->ops->preempt_wait(pfence);
+ if (err)
+ dma_fence_set_error(&pfence->base, err);
+ }
+
+ dma_fence_signal(&pfence->base);
+ pfence->ops->preempt_finished(pfence);
+
+ dma_fence_end_signalling(cookie);
+ dma_fence_put(&pfence->base);
+}
+
+/**
+ * dma_fence_is_preempt() - Is preempt fence
+ *
+ * @fence: Preempt fence
+ *
+ * Return: True if preempt fence, False otherwise
+ */
+bool dma_fence_is_preempt(const struct dma_fence *fence)
+{
+ return fence->ops == &preempt_fence_ops;
+}
+EXPORT_SYMBOL(dma_fence_is_preempt);
+
+/**
+ * dma_fence_preempt_init() - Initial preempt fence
+ *
+ * @fence: Preempt fence
+ * @ops: Preempt fence operations
+ * @resv: Dma resv which preempt fence is attached to
+ * @wq: Work queue for preempt wait
+ * @context: Fence context
+ * @seqno: Fence seqence number
+ */
+void dma_fence_preempt_init(struct dma_fence_preempt *fence,
+ const struct dma_fence_preempt_ops *ops,
+ struct dma_resv *resv, struct workqueue_struct *wq,
+ u64 context, u64 seqno)
+{
+ fence->ops = ops;
+ fence->resv = resv;
+ fence->wq = wq;
+ INIT_WORK(&fence->work, dma_fence_preempt_work_func);
+ spin_lock_init(&fence->lock);
+ dma_fence_init(&fence->base, &preempt_fence_ops,
+ &fence->lock, context, seqno);
+}
+EXPORT_SYMBOL(dma_fence_preempt_init);
diff --git a/include/linux/dma-fence-preempt.h b/include/linux/dma-fence-preempt.h
new file mode 100644
index 000000000000..9fdfe4a6b00f
--- /dev/null
+++ b/include/linux/dma-fence-preempt.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __LINUX_DMA_FENCE_PREEMPT_H
+#define __LINUX_DMA_FENCE_PREEMPT_H
+
+#include <linux/dma-fence.h>
+#include <linux/workqueue.h>
+
+struct dma_fence_preempt;
+struct dma_resv;
+
+/**
+ * struct dma_fence_preempt_ops - Preempt fence operations
+ *
+ * These functions should be implemented in the driver side.
+ */
+struct dma_fence_preempt_ops {
+ /** @preempt: Preempt execution */
+ int (*preempt)(struct dma_fence_preempt *fence);
+ /** @preempt_wait: Wait for preempt of execution to complete */
+ int (*preempt_wait)(struct dma_fence_preempt *fence);
+ /** @preempt_finished: Signal that the preempt has finished */
+ void (*preempt_finished)(struct dma_fence_preempt *fence);
+};
+
+/**
+ * struct dma_fence_preempt - Embedded preempt fence base class
+ */
+struct dma_fence_preempt {
+ /** @base: Fence base class */
+ struct dma_fence base;
+ /** @lock: Spinlock for fence handling */
+ spinlock_t lock;
+ /** @ops: Preempt fence operation */
+ const struct dma_fence_preempt_ops *ops;
+ /** @resv: DMA resv which preempt fence attached to */
+ struct dma_resv *resv;
+ /** @wq: Work queue for preempt wait */
+ struct workqueue_struct *wq;
+ /** @work: Work struct for preempt wait */
+ struct work_struct work;
+};
+
+bool dma_fence_is_preempt(const struct dma_fence *fence);
+
+void dma_fence_preempt_init(struct dma_fence_preempt *fence,
+ const struct dma_fence_preempt_ops *ops,
+ struct dma_resv *resv, struct workqueue_struct *wq,
+ u64 context, u64 seqno);
+
+#endif
--
2.34.1
next prev parent 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 ` [RFC PATCH 1/6] dma-resv: Add DMA_RESV_USAGE_PREEMPT Matthew Brost
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 ` Matthew Brost [this message]
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-4-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 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.