Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Deny unbinds if user fence pending
@ 2024-02-15 16:40 Mika Kuoppala
  2024-02-15 16:40 ` [PATCH 1/2] drm/xe: Expose user fence from xe_sync_entry Mika Kuoppala
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Mika Kuoppala @ 2024-02-15 16:40 UTC (permalink / raw)
  To: intel-xe
  Cc: Mika Kuoppala, Thomas Hellström, Matthew Brost, Jani Nikula,
	Joonas Lahtinen

If we ever want to intercept OP_MAP through
user fence, we need to make sure that sequences
of OP_MAP and OP_UNMAP can be tracked without them
coalescing and thus vanishing.

Enforce vm_bind_ioctl by enforcing wait on associated
user fences on bind, before unbinding: If there is
non signalled user fence pending when the unmap is
attempted, deny it with -EBUSY.

[1] states that -EINVAL should be returned if
the ufence was part of the previous OP_MAP inside
this ioctl. This can be added if there is need to
distinguish these apart. This series returns -EBUSY 
regardless if the OP_MAP was part of this or previous
ioctl.

[1] https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1159

Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Mika Kuoppala (2):
  drm/xe: Expose user fence from xe_sync_entry
  drm/xe: Deny unbinds if uapi ufence pending

 drivers/gpu/drm/xe/xe_sync.c       | 56 +++++++++++++++++++++++++-----
 drivers/gpu/drm/xe/xe_sync.h       |  4 +++
 drivers/gpu/drm/xe/xe_sync_types.h |  2 +-
 drivers/gpu/drm/xe/xe_vm.c         | 35 +++++++++++++++++++
 drivers/gpu/drm/xe/xe_vm_types.h   |  7 ++++
 5 files changed, 94 insertions(+), 10 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread
* [PATCH v2 0/2] Deny unbinds if user fence pending
@ 2024-02-15 18:11 Mika Kuoppala
  2024-02-15 18:11 ` [PATCH 1/2] drm/xe: Expose user fence from xe_sync_entry Mika Kuoppala
  0 siblings, 1 reply; 15+ messages in thread
From: Mika Kuoppala @ 2024-02-15 18:11 UTC (permalink / raw)
  To: intel-xe
  Cc: Mika Kuoppala, Thomas Hellström, Matthew Brost, Jani Nikula,
	Joonas Lahtinen

If we ever want to intercept OP_MAP through
user fence, we need to make sure that sequences
of OP_MAP and OP_UNMAP can be tracked without them
coalescing and thus vanishing.

Enforce vm_bind_ioctl by enforcing wait on associated
user fences on bind, before unbinding: If there is
non signalled user fence pending when the unmap is
attempted, deny it with -EBUSY.

[1] states that -EINVAL should be returned if
the ufence was part of the previous OP_MAP inside
this ioctl. This can be added if there is need to
distinguish these apart. This series returns -EBUSY 
regardless if the OP_MAP was part of this or previous
ioctl.

[1] https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1159

Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Mika Kuoppala (2):
  drm/xe: Expose user fence from xe_sync_entry
  drm/xe: Deny unbinds if uapi ufence pending

 drivers/gpu/drm/xe/xe_sync.c       | 58 ++++++++++++++++++++++++------
 drivers/gpu/drm/xe/xe_sync.h       |  4 +++
 drivers/gpu/drm/xe/xe_sync_types.h |  2 +-
 drivers/gpu/drm/xe/xe_vm.c         | 37 +++++++++++++++++++
 drivers/gpu/drm/xe/xe_vm_types.h   |  7 ++++
 5 files changed, 97 insertions(+), 11 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread
* [PATCH 1/2] drm/xe: Expose user fence from xe_sync_entry
@ 2024-02-14 14:12 Mika Kuoppala
  2024-02-15  6:18 ` Matthew Brost
  2024-02-15 11:17 ` Jani Nikula
  0 siblings, 2 replies; 15+ messages in thread
From: Mika Kuoppala @ 2024-02-14 14:12 UTC (permalink / raw)
  To: intel-xe; +Cc: Mika Kuoppala, Thomas Hellström, Matthew Brost

By allowing getting reference to user fence, we can
control the lifetime outside of sync entries.

This is needed to allow vma to track the associated
user fence that was provided with bind ioctl.

Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/xe/xe_sync.c       | 63 +++++++++++++++++++++---------
 drivers/gpu/drm/xe/xe_sync.h       |  4 ++
 drivers/gpu/drm/xe/xe_sync_types.h | 20 +++++++---
 3 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
index aab92bee1d7cf..c3e745c7778b9 100644
--- a/drivers/gpu/drm/xe/xe_sync.c
+++ b/drivers/gpu/drm/xe/xe_sync.c
@@ -19,39 +19,29 @@
 #include "xe_macros.h"
 #include "xe_sched_job_types.h"
 
-struct user_fence {
-	struct xe_device *xe;
-	struct kref refcount;
-	struct dma_fence_cb cb;
-	struct work_struct worker;
-	struct mm_struct *mm;
-	u64 __user *addr;
-	u64 value;
-};
-
 static void user_fence_destroy(struct kref *kref)
 {
-	struct user_fence *ufence = container_of(kref, struct user_fence,
+	struct xe_user_fence *ufence = container_of(kref, struct xe_user_fence,
 						 refcount);
 
 	mmdrop(ufence->mm);
 	kfree(ufence);
 }
 
-static void user_fence_get(struct user_fence *ufence)
+static void user_fence_get(struct xe_user_fence *ufence)
 {
 	kref_get(&ufence->refcount);
 }
 
-static void user_fence_put(struct user_fence *ufence)
+static void user_fence_put(struct xe_user_fence *ufence)
 {
 	kref_put(&ufence->refcount, user_fence_destroy);
 }
 
-static struct user_fence *user_fence_create(struct xe_device *xe, u64 addr,
+static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 addr,
 					    u64 value)
 {
-	struct user_fence *ufence;
+	struct xe_user_fence *ufence;
 
 	ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
 	if (!ufence)
@@ -69,7 +59,7 @@ static struct user_fence *user_fence_create(struct xe_device *xe, u64 addr,
 
 static void user_fence_worker(struct work_struct *w)
 {
-	struct user_fence *ufence = container_of(w, struct user_fence, worker);
+	struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, worker);
 
 	if (mmget_not_zero(ufence->mm)) {
 		kthread_use_mm(ufence->mm);
@@ -80,10 +70,11 @@ static void user_fence_worker(struct work_struct *w)
 	}
 
 	wake_up_all(&ufence->xe->ufence_wq);
+	WRITE_ONCE(ufence->signalled, 1);
 	user_fence_put(ufence);
 }
 
-static void kick_ufence(struct user_fence *ufence, struct dma_fence *fence)
+static void kick_ufence(struct xe_user_fence *ufence, struct dma_fence *fence)
 {
 	INIT_WORK(&ufence->worker, user_fence_worker);
 	queue_work(ufence->xe->ordered_wq, &ufence->worker);
@@ -92,7 +83,7 @@ static void kick_ufence(struct user_fence *ufence, struct dma_fence *fence)
 
 static void user_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
 {
-	struct user_fence *ufence = container_of(cb, struct user_fence, cb);
+	struct xe_user_fence *ufence = container_of(cb, struct xe_user_fence, cb);
 
 	kick_ufence(ufence, fence);
 }
@@ -340,3 +331,39 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync,
 
 	return ERR_PTR(-ENOMEM);
 }
+
+/**
+ * xe_sync_ufence_get() - Get user fence from sync
+ * @sync: input syncs
+ *
+ * Get a user fence reference from sync.
+ *
+ * Return: xe_user_fence pointer with reference
+ */
+struct xe_user_fence *xe_sync_ufence_get(struct xe_sync_entry *sync)
+{
+	user_fence_get(sync->ufence);
+
+	return sync->ufence;
+}
+
+/**
+ * xe_sync_ufence_put() - Put user fence reference
+ * @ufence: user fence reference
+ *
+ */
+void xe_sync_ufence_put(struct xe_user_fence *ufence)
+{
+	user_fence_put(ufence);
+}
+
+/**
+ * xe_sync_ufence_get_status() - Get user fence status
+ * @ufence: user fence
+ *
+ * Return: 1 if signalled, 0 not signalled, <0 on error
+ */
+int xe_sync_ufence_get_status(struct xe_user_fence *ufence)
+{
+	return READ_ONCE(ufence->signalled);
+}
diff --git a/drivers/gpu/drm/xe/xe_sync.h b/drivers/gpu/drm/xe/xe_sync.h
index f43cdcaca6c57..0fd0d51208e62 100644
--- a/drivers/gpu/drm/xe/xe_sync.h
+++ b/drivers/gpu/drm/xe/xe_sync.h
@@ -38,4 +38,8 @@ static inline bool xe_sync_is_ufence(struct xe_sync_entry *sync)
 	return !!sync->ufence;
 }
 
+struct xe_user_fence *xe_sync_ufence_get(struct xe_sync_entry *sync);
+void xe_sync_ufence_put(struct xe_user_fence *ufence);
+int xe_sync_ufence_get_status(struct xe_user_fence *ufence);
+
 #endif
diff --git a/drivers/gpu/drm/xe/xe_sync_types.h b/drivers/gpu/drm/xe/xe_sync_types.h
index 852db5e7884fc..6176ef9d65c72 100644
--- a/drivers/gpu/drm/xe/xe_sync_types.h
+++ b/drivers/gpu/drm/xe/xe_sync_types.h
@@ -7,18 +7,28 @@
 #define _XE_SYNC_TYPES_H_
 
 #include <linux/types.h>
+#include <linux/kref.h>
+#include <linux/dma-fence.h>
+#include <linux/workqueue.h>
 
-struct drm_syncobj;
-struct dma_fence;
-struct dma_fence_chain;
 struct drm_xe_sync;
-struct user_fence;
+
+struct xe_user_fence {
+	struct xe_device *xe;
+	struct kref refcount;
+	struct dma_fence_cb cb;
+	struct work_struct worker;
+	struct mm_struct *mm;
+	u64 __user *addr;
+	u64 value;
+	int signalled;
+};
 
 struct xe_sync_entry {
 	struct drm_syncobj *syncobj;
 	struct dma_fence *fence;
 	struct dma_fence_chain *chain_fence;
-	struct user_fence *ufence;
+	struct xe_user_fence *ufence;
 	u64 addr;
 	u64 timeline_value;
 	u32 type;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-02-15 18:17 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-15 16:40 [PATCH 0/2] Deny unbinds if user fence pending Mika Kuoppala
2024-02-15 16:40 ` [PATCH 1/2] drm/xe: Expose user fence from xe_sync_entry Mika Kuoppala
2024-02-15 17:13   ` Matthew Brost
2024-02-15 16:40 ` [PATCH 2/2] drm/xe: Deny unbinds if uapi ufence pending Mika Kuoppala
2024-02-15 17:21   ` Matthew Brost
2024-02-15 16:48 ` ✓ CI.Patch_applied: success for Deny unbinds if user fence pending Patchwork
2024-02-15 16:49 ` ✗ CI.checkpatch: warning " Patchwork
2024-02-15 16:50 ` ✓ CI.KUnit: success " Patchwork
2024-02-15 17:00 ` ✓ CI.Build: " Patchwork
2024-02-15 17:00 ` ✓ CI.Hooks: " Patchwork
2024-02-15 17:02 ` ✓ CI.checksparse: " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2024-02-15 18:11 [PATCH v2 0/2] " Mika Kuoppala
2024-02-15 18:11 ` [PATCH 1/2] drm/xe: Expose user fence from xe_sync_entry Mika Kuoppala
2024-02-14 14:12 Mika Kuoppala
2024-02-15  6:18 ` Matthew Brost
2024-02-15 11:17 ` Jani Nikula

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox