[PATCH 097/156] drm/nouveau/nvif: rework fault buffer "new event" api

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:39:03 UTC 2024


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/clb069.h |  8 ---
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 12 ++++
 drivers/gpu/drm/nouveau/include/nvif/event.h  |  3 +
 .../gpu/drm/nouveau/include/nvkm/core/event.h |  9 ++-
 drivers/gpu/drm/nouveau/nouveau_svm.c         |  8 ++-
 drivers/gpu/drm/nouveau/nvif/event.c          | 33 ++++++++--
 drivers/gpu/drm/nouveau/nvkm/core/uevent.c    | 65 +++++++++++++++++++
 .../gpu/drm/nouveau/nvkm/subdev/fault/user.c  | 20 ++----
 8 files changed, 126 insertions(+), 32 deletions(-)
 delete mode 100644 drivers/gpu/drm/nouveau/include/nvif/clb069.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/clb069.h b/drivers/gpu/drm/nouveau/include/nvif/clb069.h
deleted file mode 100644
index 67bf579ced18..000000000000
--- a/drivers/gpu/drm/nouveau/include/nvif/clb069.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __NVIF_CLB069_H__
-#define __NVIF_CLB069_H__
-
-union nvif_clb069_event_args {
-	struct nvif_clb069_event_vn {
-	} vn;
-};
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index ba987233ec74..81375819c787 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVIF_DRIVERIF_H__
 #define __NVIF_DRIVERIF_H__
+struct nvif_event_priv;
 struct nvif_client_priv;
 struct nvif_device_priv;
 struct nvif_control_priv;
@@ -19,6 +20,12 @@ struct nvif_driver {
 	void (*unmap)(struct nvif_client_priv *, void __iomem *ptr, u32 size);
 };
 
+struct nvif_event_impl {
+	void (*del)(struct nvif_event_priv *);
+	int (*allow)(struct nvif_event_priv *);
+	int (*block)(struct nvif_event_priv *);
+};
+
 struct nvif_mapinfo {
 	enum nvif_map_type {
 		NVIF_MAP_IO,
@@ -202,6 +209,11 @@ struct nvif_faultbuf_impl {
 	u32 entries;
 	u32 get;
 	u32 put;
+
+	struct {
+		int (*new)(struct nvif_faultbuf_priv *, u64 token,
+			   const struct nvif_event_impl **, struct nvif_event_priv **);
+	} event;
 };
 
 struct nvif_device_impl {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h
index 1683e138c7f8..338082bdc67c 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/event.h
@@ -10,7 +10,10 @@ struct nvif_event;
 typedef int (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc);
 
 struct nvif_event {
+	const struct nvif_event_impl *impl;
+	struct nvif_event_priv *priv;
 	struct nvif_object object;
+
 	nvif_event_func func;
 };
 
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
index 460459af272d..f31f0f30732a 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
@@ -4,7 +4,6 @@
 #include <core/os.h>
 struct nvkm_object;
 struct nvkm_oclass;
-struct nvkm_uevent;
 
 struct nvkm_event {
 	const struct nvkm_event_func *func;
@@ -72,6 +71,12 @@ void nvkm_event_ntfy_block(struct nvkm_event_ntfy *);
 
 typedef int (*nvkm_uevent_func)(struct nvkm_object *, u64 token, u32 bits);
 
+struct nvif_event_impl;
+struct nvif_event_priv;
+int nvkm_uevent_new_(struct nvkm_object *parent, u64 handle, struct nvkm_event *event,
+		     bool wait, int id, u32 bits, nvkm_uevent_func,
+		     const struct nvif_event_impl **, struct nvif_event_priv **);
 int nvkm_uevent_new(const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **);
-int nvkm_uevent_add(struct nvkm_uevent *, struct nvkm_event *, int id, u32 bits, nvkm_uevent_func);
+int nvkm_uevent_add(struct nvif_event_priv *, struct nvkm_event *, int id, u32 bits,
+		    nvkm_uevent_func);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c
index 43218da5d0f3..382f886e4130 100644
--- a/drivers/gpu/drm/nouveau/nouveau_svm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_svm.c
@@ -29,7 +29,6 @@
 #include <nvif/vmm.h>
 
 #include <nvif/class.h>
-#include <nvif/clb069.h>
 #include <nvif/ifc00d.h>
 
 #include <linux/sched/mm.h>
@@ -998,11 +997,14 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
 
 	INIT_WORK(&buffer->work, nouveau_svm_fault);
 
-	ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
-			      &buffer->notify);
+	ret = buffer->impl->event.new(buffer->priv, nvif_handle(&buffer->notify.object),
+				      &buffer->notify.impl, &buffer->notify.priv);
 	if (ret)
 		return ret;
 
+	nvif_event_ctor(&buffer->object, "svmFaultEvent", buffer->id, nouveau_svm_event,
+			&buffer->notify);
+
 	buffer->fault = kvcalloc(buffer->entries, sizeof(*buffer->fault), GFP_KERNEL);
 	if (!buffer->fault)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/nouveau/nvif/event.c b/drivers/gpu/drm/nouveau/nvif/event.c
index 61ff4d6eba9f..5b8ec641703b 100644
--- a/drivers/gpu/drm/nouveau/nvif/event.c
+++ b/drivers/gpu/drm/nouveau/nvif/event.c
@@ -20,6 +20,7 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <nvif/event.h>
+#include <nvif/driverif.h>
 #include <nvif/printf.h>
 
 #include <nvif/class.h>
@@ -28,29 +29,51 @@
 int
 nvif_event_block(struct nvif_event *event)
 {
-	if (nvif_event_constructed(event)) {
+	int ret;
+
+	if (!event->impl && nvif_event_constructed(event)) {
 		int ret = nvif_mthd(&event->object, NVIF_EVENT_V0_BLOCK, NULL, 0);
 		NVIF_ERRON(ret, &event->object, "[BLOCK]");
 		return ret;
 	}
-	return 0;
+
+	if (!event->impl)
+		return 0;
+
+	ret = event->impl->block(event->priv);
+	NVIF_ERRON(ret, &event->object, "[BLOCK]");
+	return ret;
 }
 
 int
 nvif_event_allow(struct nvif_event *event)
 {
-	if (nvif_event_constructed(event)) {
+	int ret;
+
+	if (!event->impl && nvif_event_constructed(event)) {
 		int ret = nvif_mthd(&event->object, NVIF_EVENT_V0_ALLOW, NULL, 0);
 		NVIF_ERRON(ret, &event->object, "[ALLOW]");
 		return ret;
 	}
-	return 0;
+
+	if (!event->impl)
+		return 0;
+
+	ret = event->impl->allow(event->priv);
+	NVIF_ERRON(ret, &event->object, "[ALLOW]");
+	return ret;
 }
 
 void
 nvif_event_dtor(struct nvif_event *event)
 {
-	nvif_object_dtor(&event->object);
+	if (!event->impl) {
+		nvif_object_dtor(&event->object);
+		return;
+	}
+
+	event->impl->del(event->priv);
+	event->impl = NULL;
 }
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c
index 900814c9a6bd..d922eebb689c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c
@@ -22,6 +22,7 @@
 #include <core/event.h>
 #include <core/client.h>
 
+#include <nvif/driverif.h>
 #include <nvif/if000e.h>
 
 struct nvif_event_priv {
@@ -71,6 +72,38 @@ nvkm_uevent_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
 	return -EINVAL;
 }
 
+static int
+nvkm_uevent_block(struct nvif_event_priv *uevent)
+{
+	nvkm_event_ntfy_block(&uevent->ntfy);
+	atomic_set(&uevent->allowed, 0);
+	return 0;
+}
+
+static int
+nvkm_uevent_allow(struct nvif_event_priv *uevent)
+{
+	nvkm_event_ntfy_allow(&uevent->ntfy);
+	atomic_set(&uevent->allowed, 1);
+	return 0;
+}
+
+static void
+nvkm_uevent_del(struct nvif_event_priv *uevent)
+{
+	struct nvkm_object *object = &uevent->object;
+
+	nvkm_object_fini(object, false);
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_event_impl
+nvkm_uevent_impl = {
+	.del = nvkm_uevent_del,
+	.allow = nvkm_uevent_allow,
+	.block = nvkm_uevent_block,
+};
+
 static int
 nvkm_uevent_fini(struct nvkm_object *object, bool suspend)
 {
@@ -154,3 +187,35 @@ nvkm_uevent_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 	uevent->ntfy.event = NULL;
 	return parent->func->uevent(parent, &args->v0.data, argc - sizeof(args->v0), uevent);
 }
+
+int
+nvkm_uevent_new_(struct nvkm_object *parent, u64 handle, struct nvkm_event *event,
+		 bool wait, int id, u32 bits, nvkm_uevent_func func,
+		 const struct nvif_event_impl **pimpl, struct nvif_event_priv **ppriv)
+{
+	struct nvif_event_priv *uevent;
+	int ret;
+
+	uevent = kzalloc(sizeof(*uevent), GFP_KERNEL);
+	if (!uevent)
+		return -ENOMEM;
+
+	nvkm_object_ctor(&nvkm_uevent, &(struct nvkm_oclass) {}, &uevent->object);
+	uevent->object.object = handle;
+	uevent->parent = parent;
+	uevent->func = NULL;
+	uevent->wait = wait;
+	uevent->ntfy.event = NULL;
+
+	ret = nvkm_uevent_add(uevent, event, id, bits, func);
+	if (ret) {
+		kfree(uevent);
+		return ret;
+	}
+
+	*pimpl = &nvkm_uevent_impl;
+	*ppriv = uevent;
+
+	nvkm_object_link(parent, &uevent->object);
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
index de7a79607eff..cbe1ead00a02 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
@@ -26,9 +26,6 @@
 #include <core/event.h>
 #include <subdev/mmu.h>
 
-#include <nvif/clb069.h>
-#include <nvif/unpack.h>
-
 struct nvif_faultbuf_priv {
 	struct nvkm_object object;
 	struct nvkm_fault_buffer *buffer;
@@ -37,18 +34,13 @@ struct nvif_faultbuf_priv {
 };
 
 static int
-nvkm_ufault_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
+nvkm_ufault_event_new(struct nvif_faultbuf_priv *ufault, u64 token,
+		      const struct nvif_event_impl **pimpl, struct nvif_event_priv **ppriv)
 {
-	struct nvkm_fault_buffer *buffer = container_of(object, struct nvif_faultbuf_priv, object)->buffer;
-	union nvif_clb069_event_args *args = argv;
-
-	if (!uevent)
-		return 0;
-	if (argc != sizeof(args->vn))
-		return -ENOSYS;
+	struct nvkm_fault_buffer *buffer = ufault->buffer;
 
-	return nvkm_uevent_add(uevent, &buffer->fault->event, buffer->id,
-			       NVKM_FAULT_BUFFER_EVENT_PENDING, NULL);
+	return nvkm_uevent_new_(&ufault->object, token, &buffer->fault->event, true, buffer->id,
+				NVKM_FAULT_BUFFER_EVENT_PENDING, NULL, pimpl, ppriv);
 }
 
 static void
@@ -63,6 +55,7 @@ nvkm_ufault_del(struct nvif_faultbuf_priv *ufault)
 static const struct nvif_faultbuf_impl
 nvkm_ufault_impl = {
 	.del = nvkm_ufault_del,
+	.event.new = nvkm_ufault_event_new,
 };
 
 static int
@@ -96,7 +89,6 @@ nvkm_ufault = {
 	.dtor = nvkm_ufault_dtor,
 	.init = nvkm_ufault_init,
 	.fini = nvkm_ufault_fini,
-	.uevent = nvkm_ufault_uevent,
 };
 
 int
-- 
2.41.0



More information about the Nouveau mailing list