[PATCH 134/156] drm/nouveau/nvif: rework device "new cgrp" api

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


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/cgrp.h   | 17 +++++
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 10 +++
 drivers/gpu/drm/nouveau/include/nvif/if0021.h | 16 -----
 drivers/gpu/drm/nouveau/nvif/Kbuild           |  1 +
 drivers/gpu/drm/nouveau/nvif/cgrp.c           | 52 ++++++++++++++
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 19 ++++++
 .../gpu/drm/nouveau/nvkm/engine/fifo/base.c   | 14 ----
 .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h   |  2 -
 .../gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c  | 67 +++++++++++++------
 .../gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.h  |  9 +++
 .../gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c    |  9 +++
 .../gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h    |  1 +
 12 files changed, 163 insertions(+), 54 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/include/nvif/cgrp.h
 delete mode 100644 drivers/gpu/drm/nouveau/include/nvif/if0021.h
 create mode 100644 drivers/gpu/drm/nouveau/nvif/cgrp.c
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/cgrp.h b/drivers/gpu/drm/nouveau/include/nvif/cgrp.h
new file mode 100644
index 000000000000..337ba67c7695
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/cgrp.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVIF_CGRP_H__
+#define __NVIF_CGRP_H__
+#include <nvif/object.h>
+#include <nvif/driverif.h>
+struct nvif_device;
+struct nvif_vmm;
+
+struct nvif_cgrp {
+	const struct nvif_cgrp_impl *impl;
+	struct nvif_cgrp_priv *priv;
+	struct nvif_object object;
+};
+
+int nvif_cgrp_ctor(struct nvif_device *, struct nvif_vmm *, int runl, struct nvif_cgrp *);
+void nvif_cgrp_dtor(struct nvif_cgrp *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 6161a29fb07f..75168621427a 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -19,6 +19,7 @@ struct nvif_outp_priv;
 struct nvif_head_priv;
 struct nvif_disp_chan_priv;
 struct nvif_ctxdma_priv;
+struct nvif_cgrp_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -430,6 +431,12 @@ struct nvif_disp_impl {
 	} chan;
 };
 
+struct nvif_cgrp_impl {
+	void (*del)(struct nvif_cgrp_priv *);
+
+	u16 id;
+};
+
 struct nvif_device_impl {
 	void (*del)(struct nvif_device_priv *);
 
@@ -546,6 +553,9 @@ struct nvif_device_impl {
 
 		struct {
 			s32 oclass;
+			int (*new)(struct nvif_device_priv *, u8 runl, struct nvif_vmm_priv *,
+				   const char *name, const struct nvif_cgrp_impl **,
+				   struct nvif_cgrp_priv **);
 		} cgrp;
 
 		struct {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0021.h b/drivers/gpu/drm/nouveau/include/nvif/if0021.h
deleted file mode 100644
index 5013def90455..000000000000
--- a/drivers/gpu/drm/nouveau/include/nvif/if0021.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_IF0021_H__
-#define __NVIF_IF0021_H__
-
-union nvif_cgrp_args {
-	struct nvif_cgrp_v0 {
-		__u8  version;
-		__u8  namelen;
-		__u8  runlist;
-		__u8  pad03[3];
-		__u16 cgid;
-		__u64 vmm;
-		__u8  name[];
-	} v0;
-};
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild
index 8e3ed36df6b3..50489933655c 100644
--- a/drivers/gpu/drm/nouveau/nvif/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvif/Kbuild
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: MIT
 nvif-y := nvif/object.o
 nvif-y += nvif/client.o
+nvif-y += nvif/cgrp.o
 nvif-y += nvif/conn.o
 nvif-y += nvif/device.o
 nvif-y += nvif/disp.o
diff --git a/drivers/gpu/drm/nouveau/nvif/cgrp.c b/drivers/gpu/drm/nouveau/nvif/cgrp.c
new file mode 100644
index 000000000000..1e968d0c0d5a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvif/cgrp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <nvif/cgrp.h>
+#include <nvif/device.h>
+#include <nvif/vmm.h>
+
+void
+nvif_cgrp_dtor(struct nvif_cgrp *cgrp)
+{
+	if (!cgrp->impl)
+		return;
+
+	cgrp->impl->del(cgrp->priv);
+	cgrp->impl = NULL;
+}
+
+int
+nvif_cgrp_ctor(struct nvif_device *device, struct nvif_vmm *vmm, int runl, struct nvif_cgrp *cgrp)
+{
+	int ret;
+
+	if (!device->impl->fifo.cgrp.new)
+		return -ENODEV;
+
+	ret = device->impl->fifo.cgrp.new(device->priv, runl, vmm->priv, "nvifCgrp",
+					  &cgrp->impl, &cgrp->priv);
+	if (ret)
+		return ret;
+
+	nvif_object_ctor(&device->object, "nvifCgrp", cgrp->impl->id,
+			 device->impl->fifo.cgrp.oclass, &cgrp->object);
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index 6a3b41004abd..f76861945cd0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -35,6 +35,7 @@
 #include <engine/disp/priv.h>
 #include <engine/disp/udisp.h>
 #include <engine/fifo/ufifo.h>
+#include <engine/fifo/ucgrp.h>
 
 struct nvif_device_priv {
 	struct nvkm_object object;
@@ -94,6 +95,22 @@ nvkm_udevice_time(struct nvif_device_priv *udev)
 	return nvkm_timer_read(udev->device->timer);
 }
 
+static int
+nvkm_udevice_cgrp_new(struct nvif_device_priv *udev, u8 runl, struct nvif_vmm_priv *uvmm,
+		      const char *name, const struct nvif_cgrp_impl **pimpl,
+		      struct nvif_cgrp_priv **ppriv)
+{
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_ucgrp_new(udev->device->fifo, runl, uvmm, name, pimpl, ppriv, &object);
+	if (ret)
+		return ret;
+
+	nvkm_object_link(&udev->object, object);
+	return 0;
+}
+
 static int
 nvkm_udevice_disp_new(struct nvif_device_priv *udev,
 		      const struct nvif_disp_impl **pimpl, struct nvif_disp_priv **ppriv)
@@ -338,6 +355,8 @@ nvkm_udevice_new(struct nvkm_device *device,
 	if (device->fifo) {
 		if (!WARN_ON(nvkm_subdev_oneinit(&device->fifo->engine.subdev))) {
 			nvkm_ufifo_ctor(device->fifo, &udev->impl.fifo);
+
+			udev->impl.fifo.cgrp.new = nvkm_udevice_cgrp_new;
 		}
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
index 6bd464da1c96..1894a2075079 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
@@ -75,9 +75,6 @@ nvkm_fifo_class_new(struct nvkm_device *device, const struct nvkm_oclass *oclass
 {
 	struct nvkm_fifo *fifo = nvkm_fifo(oclass->engine);
 
-	if (oclass->engn == &fifo->func->cgrp.user)
-		return nvkm_ucgrp_new(fifo, oclass, argv, argc, pobject);
-
 	if (oclass->engn == &fifo->func->chan.user)
 		return nvkm_uchan_new(fifo, NULL, oclass, argv, argc, pobject);
 
@@ -94,20 +91,9 @@ static int
 nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index, const struct nvkm_device_oclass **class)
 {
 	struct nvkm_fifo *fifo = nvkm_fifo(oclass->engine);
-	const struct nvkm_fifo_func_cgrp *cgrp = &fifo->func->cgrp;
 	const struct nvkm_fifo_func_chan *chan = &fifo->func->chan;
 	int c = 0;
 
-	/* *_CHANNEL_GROUP_* */
-	if (cgrp->user.oclass) {
-		if (c++ == index) {
-			oclass->base = cgrp->user;
-			oclass->engn = &fifo->func->cgrp.user;
-			*class = &nvkm_fifo_class;
-			return 0;
-		}
-	}
-
 	/* *_CHANNEL_DMA, *_CHANNEL_GPFIFO_* */
 	if (chan->user.oclass) {
 		if (c++ == index) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
index a0f3277605a5..d1386d00fc36 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
@@ -208,6 +208,4 @@ extern const struct nvkm_chan_func ga100_chan;
 
 int nvkm_uchan_new(struct nvkm_fifo *, struct nvkm_cgrp *, const struct nvkm_oclass *,
 		   void *argv, u32 argc, struct nvkm_object **);
-int nvkm_ucgrp_new(struct nvkm_fifo *, const struct nvkm_oclass *, void *argv, u32 argc,
-		   struct nvkm_object **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c
index 7c9a151b03a3..8acfd85cee53 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c
@@ -19,17 +19,18 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "priv.h"
+#include "ucgrp.h"
 #include "cgrp.h"
+#include "priv.h"
 #include "runl.h"
 
-#include <subdev/mmu.h>
-
-#include <nvif/if0021.h>
+#include <subdev/mmu/uvmm.h>
 
 struct nvif_cgrp_priv {
 	struct nvkm_object object;
 	struct nvkm_cgrp *cgrp;
+
+	struct nvif_cgrp_impl impl;
 };
 
 static int
@@ -61,6 +62,19 @@ nvkm_ucgrp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *ocl
 	return -EINVAL;
 }
 
+static void
+nvkm_ucgrp_del(struct nvif_cgrp_priv *ucgrp)
+{
+	struct nvkm_object *object = &ucgrp->object;
+
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_cgrp_impl
+nvkm_ucgrp_impl = {
+	.del = nvkm_ucgrp_del,
+};
+
 static void *
 nvkm_ucgrp_dtor(struct nvkm_object *object)
 {
@@ -77,30 +91,24 @@ nvkm_ucgrp = {
 };
 
 int
-nvkm_ucgrp_new(struct nvkm_fifo *fifo, const struct nvkm_oclass *oclass, void *argv, u32 argc,
+nvkm_ucgrp_new(struct nvkm_fifo *fifo, u8 runi, struct nvif_vmm_priv *uvmm, const char *name,
+	       const struct nvif_cgrp_impl **pimpl, struct nvif_cgrp_priv **ppriv,
 	       struct nvkm_object **pobject)
 {
-	union nvif_cgrp_args *args = argv;
 	struct nvkm_runl *runl;
 	struct nvkm_vmm *vmm;
 	struct nvif_cgrp_priv *ucgrp;
+	struct nvkm_engine *engine;
 	int ret;
 
-	if (argc < sizeof(args->v0) || args->v0.version != 0)
-		return -ENOSYS;
-	argc -= sizeof(args->v0);
-
-	if (args->v0.namelen != argc)
-		return -EINVAL;
-
 	/* Lookup objects referenced in args. */
-	runl = nvkm_runl_get(fifo, args->v0.runlist, 0);
+	runl = nvkm_runl_get(fifo, runi, 0);
 	if (!runl)
 		return -EINVAL;
 
-	vmm = nvkm_uvmm_search(oclass->client, args->v0.vmm);
-	if (IS_ERR(vmm))
-		return PTR_ERR(vmm);
+	vmm = nvkm_uvmm_ref(uvmm);
+	if (!vmm)
+		return -EINVAL;
 
 	/* Allocate channel group. */
 	if (!(ucgrp = kzalloc(sizeof(*ucgrp), GFP_KERNEL))) {
@@ -108,17 +116,32 @@ nvkm_ucgrp_new(struct nvkm_fifo *fifo, const struct nvkm_oclass *oclass, void *a
 		goto done;
 	}
 
-	nvkm_object_ctor(&nvkm_ucgrp, oclass, &ucgrp->object);
-	*pobject = &ucgrp->object;
+	engine = nvkm_engine_ref(&fifo->engine);
+	if (IS_ERR(engine)) {
+		ret = PTR_ERR(engine);
+		goto done;
+	}
 
-	ret = nvkm_cgrp_new(runl, args->v0.name, vmm, true, &ucgrp->cgrp);
-	if (ret)
+	ret = nvkm_cgrp_new(runl, name, vmm, true, &ucgrp->cgrp);
+	if (ret) {
+		nvkm_engine_unref(&engine);
 		goto done;
+	}
+
+	nvkm_object_ctor(&nvkm_ucgrp, &(struct nvkm_oclass) { .engine = engine }, &ucgrp->object);
 
 	/* Return channel group info to caller. */
-	args->v0.cgid = ucgrp->cgrp->id;
+	ucgrp->impl = nvkm_ucgrp_impl;
+	ucgrp->impl.id = ucgrp->cgrp->id;
+
+	*pimpl = &ucgrp->impl;
+	*ppriv = ucgrp;
+	*pobject = &ucgrp->object;
 
 done:
+	if (ret)
+		kfree(ucgrp);
+
 	nvkm_vmm_unref(&vmm);
 	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.h
new file mode 100644
index 000000000000..97f3d9eafdfc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UCGRP_H__
+#define __NVKM_UCGRP_H__
+#include <engine/fifo.h>
+#include <nvif/driverif.h>
+
+int nvkm_ucgrp_new(struct nvkm_fifo *, u8 runl, struct nvif_vmm_priv *,  const char *name,
+		   const struct nvif_cgrp_impl **, struct nvif_cgrp_priv **, struct nvkm_object **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
index d8e7888410c3..5fac19738815 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
@@ -33,6 +33,15 @@ struct nvif_vmm_priv {
 	struct nvif_vmm_impl impl;
 };
 
+struct nvkm_vmm *
+nvkm_uvmm_ref(struct nvif_vmm_priv *uvmm)
+{
+	if (uvmm)
+		return nvkm_vmm_ref(uvmm->vmm);
+
+	return NULL;
+}
+
 static const struct nvkm_object_func nvkm_uvmm;
 struct nvkm_vmm *
 nvkm_uvmm_search(struct nvkm_client *client, u64 handle)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h
index 51c639cd0ce0..fb2deeb01d56 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.h
@@ -6,4 +6,5 @@
 int nvkm_uvmm_new(struct nvkm_mmu *mmu, u8 type, u64 addr, u64 size,
 		  void *, u32, const struct nvif_vmm_impl **, struct nvif_vmm_priv **,
 		  struct nvkm_object **);
+struct nvkm_vmm *nvkm_uvmm_ref(struct nvif_vmm_priv *);
 #endif
-- 
2.41.0



More information about the Nouveau mailing list