[PATCH 095/156] drm/nouveau/nvif: rework device "new fault buffer" api

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


- transition from "ioctl" interfaces

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/clb069.h |  7 ---
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 12 +++++
 drivers/gpu/drm/nouveau/nouveau_svm.c         | 27 ++++++----
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 28 +++++++----
 .../gpu/drm/nouveau/nvkm/subdev/fault/base.c  |  1 -
 .../gpu/drm/nouveau/nvkm/subdev/fault/priv.h  |  3 --
 .../gpu/drm/nouveau/nvkm/subdev/fault/user.c  | 49 +++++++++++++------
 .../gpu/drm/nouveau/nvkm/subdev/fault/user.h  |  9 ++++
 8 files changed, 91 insertions(+), 45 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/clb069.h b/drivers/gpu/drm/nouveau/include/nvif/clb069.h
index d7689de35ab2..67bf579ced18 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/clb069.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/clb069.h
@@ -1,12 +1,5 @@
 #ifndef __NVIF_CLB069_H__
 #define __NVIF_CLB069_H__
-struct nvif_clb069_v0 {
-	__u8  version;
-	__u8  pad01[3];
-	__u32 entries;
-	__u32 get;
-	__u32 put;
-};
 
 union nvif_clb069_event_args {
 	struct nvif_clb069_event_vn {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 425c3184ff14..a1aab5735146 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -8,6 +8,7 @@ struct nvif_usermode_priv;
 struct nvif_mmu_priv;
 struct nvif_mem_priv;
 struct nvif_vmm_priv;
+struct nvif_faultbuf_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -194,6 +195,14 @@ struct nvif_mmu_impl {
 	} vmm;
 };
 
+struct nvif_faultbuf_impl {
+	void (*del)(struct nvif_faultbuf_priv *);
+
+	u32 entries;
+	u32 get;
+	u32 put;
+};
+
 struct nvif_device_impl {
 	void (*del)(struct nvif_device_priv *);
 
@@ -254,6 +263,9 @@ struct nvif_device_impl {
 
 	struct {
 		s32 oclass;
+		int (*new)(struct nvif_device_priv *,
+			   const struct nvif_faultbuf_impl **, struct nvif_faultbuf_priv **,
+			   u64 handle);
 	} faultbuf;
 
 	struct {
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c
index 07fa00afe5b8..83702a86da1d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_svm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_svm.c
@@ -44,8 +44,11 @@ struct nouveau_svm {
 	struct list_head inst;
 
 	struct nouveau_svm_fault_buffer {
-		int id;
+		const struct nvif_faultbuf_impl *impl;
+		struct nvif_faultbuf_priv *priv;
 		struct nvif_object object;
+
+		int id;
 		u32 entries;
 		u32 getaddr;
 		u32 putaddr;
@@ -960,7 +963,11 @@ nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id)
 	}
 
 	nvif_event_dtor(&buffer->notify);
-	nvif_object_dtor(&buffer->object);
+
+	if (buffer->impl) {
+		buffer->impl->del(buffer->priv);
+		buffer->impl = NULL;
+	}
 }
 
 static int
@@ -968,23 +975,23 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
 {
 	struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
 	struct nouveau_drm *drm = svm->drm;
-	struct nvif_object *device = &drm->client.device.object;
-	struct nvif_clb069_v0 args = {};
 	int ret;
 
 	buffer->id = id;
 
-	ret = nvif_object_ctor(device, "svmFaultBuffer", 0, oclass, &args,
-			       sizeof(args), &buffer->object);
-	if (ret < 0) {
+	ret = drm->device.impl->faultbuf.new(drm->device.priv, &buffer->impl, &buffer->priv,
+					     nvif_handle(&buffer->object));
+	if (ret) {
 		SVM_ERR(svm, "Fault buffer allocation failed: %d", ret);
 		return ret;
 	}
 
+	nvif_object_ctor(&drm->device.object, "svmFaultBuffer", id, oclass, &buffer->object);
+	buffer->entries = buffer->impl->entries;
+	buffer->getaddr = buffer->impl->get;
+	buffer->putaddr = buffer->impl->put;
+
 	nvif_object_map(&buffer->object, NULL, 0);
-	buffer->entries = args.entries;
-	buffer->getaddr = args.get;
-	buffer->putaddr = args.put;
 	INIT_WORK(&buffer->work, nouveau_svm_fault);
 
 	ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index e63462188f2a..b4604ce1fcbb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -26,6 +26,7 @@
 #include "ctrl.h"
 
 #include <core/client.h>
+#include <subdev/fault/user.h>
 #include <subdev/fb.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
@@ -41,6 +42,21 @@ struct nvif_device_priv {
 	struct nvif_device_impl impl;
 };
 
+static int
+nvkm_udevice_fault_new(struct nvif_device_priv *udev,
+		       const struct nvif_faultbuf_impl **pimpl, struct nvif_faultbuf_priv **ppriv,
+		       u64 handle)
+{
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_ufault_new(udev->device, pimpl, ppriv, &object);
+	if (ret)
+		return ret;
+
+	return nvkm_object_link_rb(udev->object.client, &udev->object, handle, object);
+}
+
 static int
 nvkm_udevice_usermode_new(struct nvif_device_priv *udev, const struct nvif_usermode_impl **pimpl,
 			  struct nvif_usermode_priv **ppriv)
@@ -183,15 +199,8 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
 		index -= engine->func->base.sclass(oclass, index, &sclass);
 	}
 
-	if (!sclass) {
-		if (device->fault && index-- == 0)
-			sclass = &device->fault->user;
-		else
-			return -EINVAL;
-
-		oclass->base = sclass->base;
-		oclass->engine = NULL;
-	}
+	if (!sclass)
+		return -EINVAL;
 
 	oclass->ctor = nvkm_udevice_child_new;
 	oclass->priv = sclass;
@@ -303,6 +312,7 @@ nvkm_udevice_new(struct nvkm_device *device,
 
 	if (device->fault) {
 		udev->impl.faultbuf.oclass = device->fault->user.base.oclass;
+		udev->impl.faultbuf.new = nvkm_udevice_fault_new;
 	}
 
 	if (device->disp) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c
index b53ac9a2552f..68611f83ab8a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c
@@ -160,7 +160,6 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device,
 		return -ENOMEM;
 	nvkm_subdev_ctor(&nvkm_fault, device, type, inst, &fault->subdev);
 	fault->func = func;
-	fault->user.ctor = nvkm_ufault_new;
 	fault->user.base = func->user.base;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h
index 3c26e76d1d3c..b49b4e3b7660 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h
@@ -52,7 +52,4 @@ void gp100_fault_intr(struct nvkm_fault *);
 u64 gp10b_fault_buffer_pin(struct nvkm_fault_buffer *);
 
 int gv100_fault_oneinit(struct nvkm_fault *);
-
-int nvkm_ufault_new(struct nvkm_device *, const struct nvkm_oclass *,
-		    void *, u32, struct nvkm_object **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
index 6c3ede8b0321..e6eb6df1f982 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
@@ -19,6 +19,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
+#include "user.h"
 #include "priv.h"
 
 #include <core/memory.h>
@@ -31,6 +32,8 @@
 struct nvif_faultbuf_priv {
 	struct nvkm_object object;
 	struct nvkm_fault_buffer *buffer;
+
+	struct nvif_faultbuf_impl impl;
 };
 
 static int
@@ -60,6 +63,20 @@ nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
 	return 0;
 }
 
+static void
+nvkm_ufault_del(struct nvif_faultbuf_priv *ufault)
+{
+	struct nvkm_object *object = &ufault->object;
+
+	nvkm_object_fini(object, false);
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_faultbuf_impl
+nvkm_ufault_impl = {
+	.del = nvkm_ufault_del,
+};
+
 static int
 nvkm_ufault_fini(struct nvkm_object *object, bool suspend)
 {
@@ -96,31 +113,33 @@ nvkm_ufault = {
 };
 
 int
-nvkm_ufault_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
-		void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_ufault_new(struct nvkm_device *device, const struct nvif_faultbuf_impl **pimpl,
+		struct nvif_faultbuf_priv **ppriv, struct nvkm_object **pobject)
 {
-	union {
-		struct nvif_clb069_v0 v0;
-	} *args = argv;
 	struct nvkm_fault *fault = device->fault;
 	struct nvif_faultbuf_priv *ufault;
-	struct nvkm_fault_buffer *buffer = fault->buffer[fault->func->user.rp];
-	int ret = -ENOSYS;
-
-	if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-		args->v0.entries = buffer->entries;
-		args->v0.get = buffer->get;
-		args->v0.put = buffer->put;
-	} else
-		return ret;
+	int ret;
 
 	ufault = kzalloc(sizeof(*ufault), GFP_KERNEL);
 	if (!ufault)
 		return -ENOMEM;
 
-	nvkm_object_ctor(&nvkm_ufault, oclass, &ufault->object);
+	nvkm_object_ctor(&nvkm_ufault, &(struct nvkm_oclass) {}, &ufault->object);
 	ufault->buffer = fault->buffer[fault->func->user.rp];
 
+	ret = nvkm_ufault_init(&ufault->object);
+	if (ret) {
+		nvkm_ufault_del(ufault);
+		return ret;
+	}
+
+	ufault->impl = nvkm_ufault_impl;
+	ufault->impl.entries = ufault->buffer->entries;
+	ufault->impl.get = ufault->buffer->get;
+	ufault->impl.put = ufault->buffer->put;
+
+	*pimpl = &ufault->impl;
+	*ppriv = ufault;
 	*pobject = &ufault->object;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.h
new file mode 100644
index 000000000000..2408aa3ec91c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UFAULT_H__
+#define __NVKM_UFAULT_H__
+#include <subdev/fault.h>
+#include <nvif/driverif.h>
+
+int nvkm_ufault_new(struct nvkm_device *, const struct nvif_faultbuf_impl **,
+		    struct nvif_faultbuf_priv **, struct nvkm_object **);
+#endif
-- 
2.41.0



More information about the Nouveau mailing list