[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