[PATCH 20/60] drm/nouveau/gsp: use internal.{client, device, subdevice} where possible

Ben Skeggs bskeggs at nvidia.com
Tue Apr 29 23:38:48 UTC 2025


As nouveau never directly exposes RMAPI to userspace, there's no real
reason why we need to be creating client/device/subdevice objects for
every client.  Instead, use the object handles provided by GSP during
initialisation.

This prevents 4x RPCs to GSP every time the nouveau FD is opened.

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 .../drm/nouveau/include/nvkm/engine/disp.h    |  3 ---
 .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h |  6 ++++--
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   |  2 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c  |  4 ++--
 .../nouveau/nvkm/subdev/gsp/rm/r535/disp.c    | 19 +++++++------------
 .../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c    |  8 ++++----
 .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c  |  8 ++++----
 .../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c |  7 ++++++-
 .../drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c | 17 ++++++++++-------
 .../gpu/drm/nouveau/nvkm/subdev/mmu/base.c    |  1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c |  7 ++++---
 11 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
index 7903d7470d19..48dc7ec42164 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
@@ -12,9 +12,6 @@ struct nvkm_disp {
 	struct nvkm_engine engine;
 
 	struct {
-		struct nvkm_gsp_client client;
-		struct nvkm_gsp_device device;
-
 		struct nvkm_gsp_object objcom;
 		struct nvkm_gsp_object object;
 
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
index 935b1cacd528..5320e15f4fc8 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -68,8 +68,6 @@ struct nvkm_vmm {
 	struct {
 		u64 bar2_pdb;
 
-		struct nvkm_gsp_client client;
-		struct nvkm_gsp_device device;
 		struct nvkm_gsp_object object;
 
 		struct nvkm_vma *rsvd;
@@ -148,6 +146,10 @@ struct nvkm_mmu {
 	struct mutex mutex; /* serialises mmu invalidations */
 
 	struct nvkm_device_oclass user;
+
+	struct {
+		struct ida vmm_ids;
+	} rm;
 };
 
 int nv04_mmu_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mmu **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index 28adc5a30f2f..02de74b406a3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -386,7 +386,7 @@ nvkm_outp_new_(const struct nvkm_outp_func *func, struct nvkm_disp *disp,
 	outp->disp = disp;
 	outp->index = index;
 	outp->info = *dcbE;
-	if (!disp->rm.client.gsp)
+	if (!disp->rm.objcom.client)
 		outp->i2c = nvkm_i2c_bus_find(i2c, dcbE->i2c_index);
 
 	OUTP_DBG(outp, "type %02x loc %d or %d link %d con %x "
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
index 2dab6612c4fc..f9398c5576ff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
@@ -102,7 +102,7 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
 	u64 bits = 0;
 
 	if (!uevent) {
-		if (!disp->rm.client.gsp && conn->info.hpd == DCB_GPIO_UNUSED)
+		if (!disp->rm.objcom.client && conn->info.hpd == DCB_GPIO_UNUSED)
 			return -ENOSYS;
 		return 0;
 	}
@@ -118,7 +118,7 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
 	if (&outp->head == &conn->disp->outps)
 		return -EINVAL;
 
-	if (disp->rm.client.gsp) {
+	if (disp->rm.objcom.client) {
 		if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_DPYID_PLUG;
 		if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_DPYID_UNPLUG;
 		if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_DPYID_IRQ;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
index e65f9074e94f..03222631d847 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
@@ -150,7 +150,7 @@ r535_dmac_bind(struct nvkm_disp_chan *chan, struct nvkm_object *object, u32 hand
 {
 	return nvkm_ramht_insert(chan->disp->ramht, object, chan->chid.user, -9, handle,
 				 chan->chid.user << 25 |
-				 (chan->disp->rm.client.object.handle & 0x3fff));
+				 (chan->rm.object.client->object.handle & 0x3fff));
 }
 
 static void
@@ -1414,17 +1414,16 @@ r535_disp_fini(struct nvkm_disp *disp, bool suspend)
 		nvkm_event_fini(&disp->rm.event);
 
 		nvkm_gsp_rm_free(&disp->rm.objcom);
-		nvkm_gsp_device_dtor(&disp->rm.device);
-		nvkm_gsp_client_dtor(&disp->rm.client);
 	}
 }
 
 static int
 r535_disp_init(struct nvkm_disp *disp)
 {
+	struct nvkm_gsp *gsp = disp->engine.subdev.device->gsp;
 	int ret;
 
-	ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, disp->func->root.oclass << 16,
+	ret = nvkm_gsp_rm_alloc(&gsp->internal.device.object, disp->func->root.oclass << 16,
 				disp->func->root.oclass, 0, &disp->rm.object);
 	if (ret)
 		return ret;
@@ -1464,11 +1463,7 @@ r535_disp_oneinit(struct nvkm_disp *disp)
 		return ret;
 
 	/* OBJs. */
-	ret = nvkm_gsp_client_device_ctor(gsp, &disp->rm.client, &disp->rm.device);
-	if (ret)
-		return ret;
-
-	ret = nvkm_gsp_rm_alloc(&disp->rm.device.object, 0x00730000, NV04_DISPLAY_COMMON, 0,
+	ret = nvkm_gsp_rm_alloc(&gsp->internal.device.object, 0x00730000, NV04_DISPLAY_COMMON, 0,
 				&disp->rm.objcom);
 	if (ret)
 		return ret;
@@ -1491,7 +1486,7 @@ r535_disp_oneinit(struct nvkm_disp *disp)
 	{
 #if defined(CONFIG_ACPI) && defined(CONFIG_X86)
 		NV2080_CTRL_INTERNAL_INIT_BRIGHTC_STATE_LOAD_PARAMS *ctrl;
-		struct nvkm_gsp_object *subdevice = &disp->rm.client.gsp->internal.device.subdevice;
+		struct nvkm_gsp_object *subdevice = &gsp->internal.device.subdevice;
 
 		ctrl = nvkm_gsp_rm_ctrl_get(subdevice,
 					    NV2080_CTRL_CMD_INTERNAL_INIT_BRIGHTC_STATE_LOAD,
@@ -1639,12 +1634,12 @@ r535_disp_oneinit(struct nvkm_disp *disp)
 	if (WARN_ON(ret))
 		return ret;
 
-	ret = nvkm_gsp_device_event_ctor(&disp->rm.device, 0x007e0000, NV2080_NOTIFIERS_HOTPLUG,
+	ret = nvkm_gsp_device_event_ctor(&gsp->internal.device, 0x007e0000, NV2080_NOTIFIERS_HOTPLUG,
 					 r535_disp_hpd, &disp->rm.hpd);
 	if (ret)
 		return ret;
 
-	ret = nvkm_gsp_device_event_ctor(&disp->rm.device, 0x007e0001, NV2080_NOTIFIERS_DP_IRQ,
+	ret = nvkm_gsp_device_event_ctor(&gsp->internal.device, 0x007e0001, NV2080_NOTIFIERS_DP_IRQ,
 					 r535_disp_irq, &disp->rm.irq);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
index eb1531c3eabd..b4e5112cbad8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
@@ -101,7 +101,7 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm,
 	if (!chan->rm.mthdbuf.ptr)
 		return -ENOMEM;
 
-	args = nvkm_gsp_rm_alloc_get(&chan->vmm->rm.device.object, 0xf1f00000 | chan->id,
+	args = nvkm_gsp_rm_alloc_get(&device->gsp->internal.device.object, 0xf1f00000 | chan->id,
 				     fifo->func->chan.user.oclass, sizeof(*args),
 				     &chan->rm.object);
 	if (WARN_ON(IS_ERR(args)))
@@ -373,10 +373,10 @@ r535_gr = {
 static int
 r535_flcn_bind(struct nvkm_engn *engn, struct nvkm_vctx *vctx, struct nvkm_chan *chan)
 {
-	struct nvkm_gsp_client *client = &chan->vmm->rm.client;
+	struct nvkm_gsp_client *client = chan->rm.object.client;
 	NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS *ctrl;
 
-	ctrl = nvkm_gsp_rm_ctrl_get(&chan->vmm->rm.device.subdevice,
+	ctrl = nvkm_gsp_rm_ctrl_get(&client->gsp->internal.device.subdevice,
 				    NV2080_CTRL_CMD_GPU_PROMOTE_CTX, sizeof(*ctrl));
 	if (IS_ERR(ctrl))
 		return PTR_ERR(ctrl);
@@ -389,7 +389,7 @@ r535_flcn_bind(struct nvkm_engn *engn, struct nvkm_vctx *vctx, struct nvkm_chan
 	ctrl->engineType = engn->id;
 	ctrl->ChID = chan->id;
 
-	return nvkm_gsp_rm_ctrl_wr(&chan->vmm->rm.device.subdevice, ctrl);
+	return nvkm_gsp_rm_ctrl_wr(&client->gsp->internal.device.subdevice, ctrl);
 }
 
 static int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
index c7d1d6081eae..e9d3082309ce 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
@@ -64,13 +64,13 @@ r535_gr_promote_ctx(struct r535_gr *gr, bool golden, struct nvkm_vmm *vmm,
 	struct nvkm_device *device = subdev->device;
 	NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS *ctrl;
 
-	ctrl = nvkm_gsp_rm_ctrl_get(&vmm->rm.device.subdevice,
+	ctrl = nvkm_gsp_rm_ctrl_get(&device->gsp->internal.device.subdevice,
 				    NV2080_CTRL_CMD_GPU_PROMOTE_CTX, sizeof(*ctrl));
 	if (WARN_ON(IS_ERR(ctrl)))
 		return PTR_ERR(ctrl);
 
 	ctrl->engineType = 1;
-	ctrl->hChanClient = vmm->rm.client.object.handle;
+	ctrl->hChanClient = chan->client->object.handle;
 	ctrl->hObject = chan->handle;
 
 	for (int i = 0; i < gr->ctxbuf_nr; i++) {
@@ -135,7 +135,7 @@ r535_gr_promote_ctx(struct r535_gr *gr, bool golden, struct nvkm_vmm *vmm,
 		ctrl->entryCount++;
 	}
 
-	return nvkm_gsp_rm_ctrl_wr(&vmm->rm.device.subdevice, ctrl);
+	return nvkm_gsp_rm_ctrl_wr(&device->gsp->internal.device.subdevice, ctrl);
 }
 
 int
@@ -203,7 +203,7 @@ r535_gr_oneinit(struct nvkm_gr *base)
 	{
 		NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args;
 
-		args = nvkm_gsp_rm_alloc_get(&golden.vmm->rm.device.object, 0xf1f00000,
+		args = nvkm_gsp_rm_alloc_get(&gsp->internal.device.object, 0xf1f00000,
 					     device->fifo->func->chan.user.oclass,
 					     sizeof(*args), &golden.chan);
 		if (IS_ERR(args)) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index 5e6cf57a6f70..195dd35393d9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -179,6 +179,7 @@ r535_gsp_rpc_get_gsp_static_info(struct nvkm_gsp *gsp)
 	gsp->internal.client.object.parent = NULL;
 	gsp->internal.client.object.handle = rpc->hInternalClient;
 	gsp->internal.client.gsp = gsp;
+	INIT_LIST_HEAD(&gsp->internal.client.events);
 
 	gsp->internal.device.object.client = &gsp->internal.client;
 	gsp->internal.device.object.parent = &gsp->internal.client.object;
@@ -967,7 +968,11 @@ r535_gsp_msg_post_event(void *priv, u32 fn, void *repv, u32 repc)
 		   msg->status, msg->eventDataSize, msg->bNotifyList);
 
 	mutex_lock(&gsp->client_id.mutex);
-	client = idr_find(&gsp->client_id.idr, msg->hClient & 0xffff);
+	if (msg->hClient == gsp->internal.client.object.handle)
+		client = &gsp->internal.client;
+	else
+		client = idr_find(&gsp->client_id.idr, msg->hClient & 0xffff);
+
 	if (client) {
 		struct nvkm_gsp_event *event;
 		bool handled = false;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
index c697885c65d3..9c6f6901ec45 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c
@@ -27,17 +27,20 @@ static int
 r535_mmu_promote_vmm(struct nvkm_vmm *vmm)
 {
 	NV_VASPACE_ALLOCATION_PARAMETERS *args;
-	int ret;
+	struct nvkm_mmu *mmu = vmm->mmu;
+	struct nvkm_gsp *gsp = mmu->subdev.device->gsp;
+	int id, ret;
 
-	ret = nvkm_gsp_client_device_ctor(vmm->mmu->subdev.device->gsp,
-					  &vmm->rm.client, &vmm->rm.device);
-	if (ret)
-		return ret;
+	id = ida_alloc_range(&mmu->rm.vmm_ids, 0, 0xffff + 1, GFP_KERNEL);
+	if (id < 0)
+		return id;
 
-	args = nvkm_gsp_rm_alloc_get(&vmm->rm.device.object, 0x90f10000, FERMI_VASPACE_A,
+	args = nvkm_gsp_rm_alloc_get(&gsp->internal.device.object, 0x90f10000 | id, FERMI_VASPACE_A,
 				     sizeof(*args), &vmm->rm.object);
-	if (IS_ERR(args))
+	if (IS_ERR(args)) {
+		ida_free(&mmu->rm.vmm_ids, id);
 		return PTR_ERR(args);
+	}
 
 	args->index = NV_VASPACE_ALLOCATION_INDEX_GPU_NEW;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
index b67ace7ae93c..eb31c54b53ad 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
@@ -428,6 +428,7 @@ nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device,
 	mutex_init(&mmu->mutex);
 	mmu->user.ctor = nvkm_ummu_new;
 	mmu->user.base = func->mmu.user;
+	ida_init(&mmu->rm.vmm_ids);
 }
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index 9c97800fe037..0768e5c1fad4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -1027,13 +1027,14 @@ nvkm_vmm_dump(struct nvkm_vmm *vmm)
 static void
 nvkm_vmm_dtor(struct nvkm_vmm *vmm)
 {
+	struct nvkm_mmu *mmu = vmm->mmu;
 	struct nvkm_vma *vma;
 	struct rb_node *node;
 
-	if (vmm->rm.client.gsp) {
+	if (vmm->rm.object.client) {
+		unsigned int id = vmm->rm.object.handle & 0xffff;
 		nvkm_gsp_rm_free(&vmm->rm.object);
-		nvkm_gsp_device_dtor(&vmm->rm.device);
-		nvkm_gsp_client_dtor(&vmm->rm.client);
+		ida_free(&mmu->rm.vmm_ids, id);
 		nvkm_vmm_put(vmm, &vmm->rm.rsvd);
 	}
 
-- 
2.49.0



More information about the Nouveau mailing list