[RFC 14/29] nvkm/vgpu: introduce channel allocation for vGPU

Zhi Wang
2024-09-22T12:50:45Z

Creating a vGPU requires allocating a portion of the CHIDs from the
reserved channel pool.

Expose the routine of allocating the channels from the reserved channel
pool to NVIDIA vGPU VFIO module for creating a vGPU.

Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
.../nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h | 2 ++
drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c | 28 +++++++++++++++++++
.../gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c | 2 ++
include/drm/nvkm_vgpu_mgr_vfio.h | 2 ++
4 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
index 5a856fa905f9..a351e8bfc772 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/vgpu_mgr/vgpu_mgr.h
@@ -22,6 +22,8 @@ struct nvkm_vgpu_mgr {

void *vfio_ops;
struct nvidia_vgpu_vfio_handle_data vfio_handle_data;
+
+ struct mutex chid_alloc_lock;
};

bool nvkm_vgpu_mgr_is_supported(struct nvkm_device *device);
diff --git a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c
index 9732e43a5d6b..44d901a0474d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c
+++ b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vfio.c
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: MIT */

#include <core/device.h>
+#include <engine/chid.h>
+#include <engine/fifo.h>
+#include <subdev/fb.h>
#include <subdev/gsp.h>

#include <vgpu_mgr/vgpu_mgr.h>
@@ -128,6 +131,29 @@ static void rm_ctrl_done(struct nvidia_vgpu_gsp_client *client, void *ctrl)
nvkm_gsp_rm_ctrl_done(&device->subdevice, ctrl);
}

+static void free_chids(void *handle, int offset, int count)
+{
+ struct nvkm_device *device = handle;
+ struct nvkm_vgpu_mgr *vgpu_mgr = &device->vgpu_mgr;
+
+ mutex_lock(&vgpu_mgr->chid_alloc_lock);
+ nvkm_chid_reserved_free(device->fifo->chid, offset, count);
+ mutex_unlock(&vgpu_mgr->chid_alloc_lock);
+}
+
+static int alloc_chids(void *handle, int count)
+{
+ struct nvkm_device *device = handle;
+ struct nvkm_vgpu_mgr *vgpu_mgr = &device->vgpu_mgr;
+ int ret;
+
+ mutex_lock(&vgpu_mgr->chid_alloc_lock);
+ ret = nvkm_chid_reserved_alloc(device->fifo->chid, count);
+ mutex_unlock(&vgpu_mgr->chid_alloc_lock);
+
+ return ret;
+}
+
struct nvkm_vgpu_mgr_vfio_ops nvkm_vgpu_mgr_vfio_ops = {
.vgpu_mgr_is_enabled = vgpu_mgr_is_enabled,
.get_handle = get_handle,
@@ -140,6 +166,8 @@ struct nvkm_vgpu_mgr_vfio_ops nvkm_vgpu_mgr_vfio_ops = {
.rm_ctrl_wr = rm_ctrl_wr,
.rm_ctrl_rd = rm_ctrl_rd,
.rm_ctrl_done = rm_ctrl_done,
+ .alloc_chids = alloc_chids,
+ .free_chids = free_chids,
};

/**
diff --git a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
index caeb805cf1c3..3654bd43b68a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/vgpu_mgr/vgpu_mgr.c
@@ -127,6 +127,8 @@ int nvkm_vgpu_mgr_init(struct nvkm_device *device)

vgpu_mgr->nvkm_dev = device;

+ mutex_init(&vgpu_mgr->chid_alloc_lock);
+
ret = attach_nvkm(vgpu_mgr);
if (ret)
return ret;
diff --git a/include/drm/nvkm_vgpu_mgr_vfio.h b/include/drm/nvkm_vgpu_mgr_vfio.h
index 29ff9b39d0b2..001306fb0b5b 100644
--- a/include/drm/nvkm_vgpu_mgr_vfio.h
+++ b/include/drm/nvkm_vgpu_mgr_vfio.h
@@ -35,6 +35,8 @@ struct nvkm_vgpu_mgr_vfio_ops {
u32 size);
void (*rm_ctrl_done)(struct nvidia_vgpu_gsp_client *client,
void *ctrl);
+ int (*alloc_chids)(void *handle, int count);
+ void (*free_chids)(void *handle, int offset, int count);
};

struct nvkm_vgpu_mgr_vfio_ops *nvkm_vgpu_mgr_get_vfio_ops(void *handle);
--
2.34.1