[PATCH 075/156] drm/nouveau/nvif: rework device "new usermode" api

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:38:41 UTC 2024


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 .../gpu/drm/nouveau/include/nvif/driverif.h   |  8 +++++
 drivers/gpu/drm/nouveau/include/nvif/user.h   |  5 +++-
 drivers/gpu/drm/nouveau/nouveau_dma.c         |  2 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c         |  2 +-
 drivers/gpu/drm/nouveau/nvif/user.c           | 16 ++++++----
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 19 ++++++++++--
 .../gpu/drm/nouveau/nvkm/subdev/vfn/base.c    |  1 -
 .../gpu/drm/nouveau/nvkm/subdev/vfn/priv.h    |  3 --
 .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c    | 29 +++++++++++++++----
 .../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h    |  9 ++++++
 10 files changed, 73 insertions(+), 21 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 05d69ea0f002..35a5869eb036 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -4,6 +4,7 @@
 struct nvif_client_priv;
 struct nvif_device_priv;
 struct nvif_control_priv;
+struct nvif_usermode_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -69,6 +70,10 @@ struct nvif_control_impl {
 	} pstate;
 };
 
+struct nvif_usermode_impl {
+	void (*del)(struct nvif_usermode_priv *);
+};
+
 struct nvif_device_impl {
 	void (*del)(struct nvif_device_priv *);
 
@@ -117,6 +122,9 @@ struct nvif_device_impl {
 
 	struct {
 		s32 oclass;
+		int (*new)(struct nvif_device_priv *,
+			   const struct nvif_usermode_impl **, struct nvif_usermode_priv **,
+			   u64 handle);
 	} usermode;
 
 	struct {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/user.h b/drivers/gpu/drm/nouveau/include/nvif/user.h
index 146986a9fe53..51104955c1e3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/user.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/user.h
@@ -4,8 +4,11 @@
 struct nvif_device;
 
 struct nvif_user {
-	const struct nvif_user_func *func;
+	const struct nvif_usermode_impl *impl;
+	struct nvif_usermode_priv *priv;
 	struct nvif_object object;
+
+	const struct nvif_user_func *func;
 };
 
 struct nvif_user_func {
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index a1f329ef0641..83eb9c9fa67e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -72,7 +72,7 @@ void
 nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length,
 	      bool no_prefetch)
 {
-	struct nvif_user *user = &chan->cli->drm->client.device.user;
+	struct nvif_user *user = &chan->cli->drm->device.user;
 	struct nouveau_bo *pb = chan->push.buffer;
 	int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 76990dde1b6a..a91ad8e65a0f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -474,7 +474,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
 
 	/* Volta requires access to a doorbell register for kickoff. */
 	if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_VOLTA) {
-		ret = nvif_user_ctor(device, "drmUsermode");
+		ret = nvif_user_ctor(&drm->device, "drmUsermode");
 		if (ret)
 			return;
 	}
diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c
index d8d37c1c8169..878883aff9c5 100644
--- a/drivers/gpu/drm/nouveau/nvif/user.c
+++ b/drivers/gpu/drm/nouveau/nvif/user.c
@@ -21,6 +21,7 @@
  */
 #include <nvif/user.h>
 #include <nvif/device.h>
+#include <nvif/driverif.h>
 #include <nvif/printf.h>
 
 #include <nvif/class.h>
@@ -28,8 +29,9 @@
 void
 nvif_user_dtor(struct nvif_device *device)
 {
-	if (device->user.func) {
-		nvif_object_dtor(&device->user.object);
+	if (device->user.impl) {
+		device->user.impl->del(device->user.priv);
+		device->user.impl = NULL;
 		device->user.func = NULL;
 	}
 }
@@ -53,13 +55,15 @@ nvif_user_ctor(struct nvif_device *device, const char *name)
 		return -ENODEV;
 	}
 
-	ret = nvif_object_ctor(&device->object, name ? name : "nvifUsermode",
-			       0, oclass, NULL, 0,
-			       &device->user.object);
+	ret = device->impl->usermode.new(device->priv, &device->user.impl, &device->user.priv,
+					 nvif_handle(&device->user.object));
+	NVIF_ERRON(ret, &device->object, "[NEW usermode%04x]", oclass);
 	if (ret)
 		return ret;
 
-	nvif_object_map(&device->user.object, NULL, 0);
+	nvif_object_ctor(&device->object, name ?: "nvifUsermode", 0, oclass, &device->user.object);
 	device->user.func = func;
+
+	nvif_object_map(&device->user.object, NULL, 0);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index 97d54b812165..aadd0c0956ee 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -29,6 +29,7 @@
 #include <subdev/fb.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
+#include <subdev/vfn/uvfn.h>
 #include <engine/disp/priv.h>
 #include <engine/fifo/ufifo.h>
 
@@ -39,6 +40,20 @@ struct nvif_device_priv {
 	struct nvif_device_impl impl;
 };
 
+static int
+nvkm_udevice_usermode_new(struct nvif_device_priv *udev, const struct nvif_usermode_impl **pimpl,
+			  struct nvif_usermode_priv **ppriv, u64 handle)
+{
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_uvfn_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_control_new(struct nvif_device_priv *udev,
 			 const struct nvif_control_impl **pimpl, struct nvif_control_priv **ppriv)
@@ -74,6 +89,7 @@ nvkm_udevice_impl = {
 	.del = nvkm_udevice_del,
 	.time = nvkm_udevice_time,
 	.control.new = nvkm_udevice_control_new,
+	.usermode.new = nvkm_udevice_usermode_new,
 };
 
 static int
@@ -154,8 +170,6 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
 			sclass = &device->mmu->user;
 		else if (device->fault && index-- == 0)
 			sclass = &device->fault->user;
-		else if (device->vfn && index-- == 0)
-			sclass = &device->vfn->user;
 		else
 			return -EINVAL;
 
@@ -263,6 +277,7 @@ nvkm_udevice_new(struct nvkm_device *device,
 
 	if (device->vfn) {
 		udev->impl.usermode.oclass = device->vfn->user.base.oclass;
+		udev->impl.usermode.new = nvkm_udevice_usermode_new;
 	}
 
 	if (device->mmu) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
index 62e81d551f44..2215de6c4803 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
@@ -54,7 +54,6 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct nvkm_device *device,
 			return ret;
 	}
 
-	vfn->user.ctor = nvkm_uvfn_new;
 	vfn->user.base = func->user.base;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
index 3a09781ad032..40245777c600 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
@@ -24,7 +24,4 @@ int nvkm_vfn_new_(const struct nvkm_vfn_func *, struct nvkm_device *, enum nvkm_
 		  u32 addr, struct nvkm_vfn **);
 
 extern const struct nvkm_intr_func tu102_vfn_intr;
-
-int nvkm_uvfn_new(struct nvkm_device *, const struct nvkm_oclass *, void *, u32,
-		  struct nvkm_object **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
index fe35024d69ba..6b0ddeb1f568 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.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 "uvfn.h"
 #include "priv.h"
 
 #include <core/object.h>
@@ -26,6 +27,8 @@
 struct nvif_usermode_priv {
 	struct nvkm_object object;
 	struct nvkm_vfn *vfn;
+
+	struct nvif_usermode_impl impl;
 };
 
 static int
@@ -41,26 +44,40 @@ nvkm_uvfn_map(struct nvkm_object *object, void *argv, u32 argc,
 	return 0;
 }
 
+static void
+nvkm_uvfn_del(struct nvif_usermode_priv *uvfn)
+{
+	struct nvkm_object *object = &uvfn->object;
+
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_usermode_impl
+nvkm_uvfn_impl = {
+	.del = nvkm_uvfn_del,
+};
+
 static const struct nvkm_object_func
 nvkm_uvfn = {
 	.map = nvkm_uvfn_map,
 };
 
 int
-nvkm_uvfn_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
-	      void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_uvfn_new(struct nvkm_device *device, const struct nvif_usermode_impl **pimpl,
+	      struct nvif_usermode_priv **ppriv, struct nvkm_object **pobject)
 {
 	struct nvif_usermode_priv *uvfn;
 
-	if (argc != 0)
-		return -ENOSYS;
-
 	if (!(uvfn = kzalloc(sizeof(*uvfn), GFP_KERNEL)))
 		return -ENOMEM;
 
-	nvkm_object_ctor(&nvkm_uvfn, oclass, &uvfn->object);
+	nvkm_object_ctor(&nvkm_uvfn, &(struct nvkm_oclass) {}, &uvfn->object);
 	uvfn->vfn = device->vfn;
 
+	uvfn->impl = nvkm_uvfn_impl;
+
+	*pimpl = &uvfn->impl;
+	*ppriv = uvfn;
 	*pobject = &uvfn->object;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
new file mode 100644
index 000000000000..23f636eb3b58
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UVFN_H__
+#define __NVKM_UVFN_H__
+#include <subdev/vfn.h>
+#include <nvif/driverif.h>
+
+int nvkm_uvfn_new(struct nvkm_device *, const struct nvif_usermode_impl **,
+		  struct nvif_usermode_priv **, struct nvkm_object **);
+#endif
-- 
2.41.0



More information about the Nouveau mailing list