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 <bske...@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