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

Reply via email to