From 5f6ff29aea24230d2eefaa1301579d75e5c91325 Mon Sep 17 00:00:00 2001 From: Sami Kiminki Date: Mon, 24 May 2021 16:49:36 +0300 Subject: [PATCH] gpu: nvgpu: report number of syncpoints in nvgpu_as_get_sync_ro_map_arg Add reporting for the number of syncpoints when mapping the RO shim. This allows the userspace to perform boundary condition checks when computing the GPU VA for a syncpoint. JIRA GCSS-1579 Change-Id: Ia6c9eee917d2c1e08f9905701e03f2b09e01ba60 Signed-off-by: Sami Kiminki Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2533981 Reviewed-by: Seshendra Gadagottu Reviewed-by: Lakshmanan M Reviewed-by: Deepak Nibade Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b.h | 2 +- drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b_fusa.c | 6 +++++- .../gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.c | 6 +++++- .../gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.h | 2 +- drivers/gpu/nvgpu/include/nvgpu/gops/sync.h | 9 ++++++--- drivers/gpu/nvgpu/os/linux/ioctl_as.c | 5 ++++- include/uapi/linux/nvgpu-as.h | 2 +- userspace/units/sync/nvgpu-sync.c | 3 ++- 8 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b.h b/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b.h index 9a528453a..6dcf29db6 100644 --- a/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b.h +++ b/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b.h @@ -52,7 +52,7 @@ int gv11b_syncpt_alloc_buf(struct nvgpu_channel *c, u32 syncpt_id, struct nvgpu_mem *syncpt_buf); int gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, - u64 *base_gpuva, u32 *sync_size); + u64 *base_gpuva, u32 *sync_size, u32 *num_syncpoints); #else diff --git a/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b_fusa.c index 1a39ca354..a870fdc77 100644 --- a/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/sync/syncpt_cmdbuf_gv11b_fusa.c @@ -105,10 +105,11 @@ void gv11b_syncpt_free_buf(struct nvgpu_channel *c, } int gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, - u64 *base_gpuva, u32 *sync_size) + u64 *base_gpuva, u32 *sync_size, u32 *num_syncpoints) { struct gk20a *g = gk20a_from_vm(vm); int err; + size_t tmp; nvgpu_mutex_acquire(&vm->syncpt_ro_map_lock); err = set_syncpt_ro_map_gpu_va_locked(vm); @@ -120,5 +121,8 @@ int gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, *base_gpuva = vm->syncpt_ro_map_gpu_va; *sync_size = g->syncpt_size; + tmp = g->syncpt_size ? (g->syncpt_unit_size / g->syncpt_size) : 0U; + *num_syncpoints = (tmp <= U32_MAX) ? tmp : U32_MAX; + return 0; } diff --git a/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.c b/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.c index 705c040d5..f180ecdc2 100644 --- a/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.c +++ b/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.c @@ -131,10 +131,11 @@ void vgpu_gv11b_syncpt_free_buf(struct nvgpu_channel *c, } int vgpu_gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, - u64 *base_gpuva, u32 *sync_size) + u64 *base_gpuva, u32 *sync_size, u32 *num_syncpoints) { struct gk20a *g = gk20a_from_vm(vm); int err; + size_t tmp; nvgpu_mutex_acquire(&vm->syncpt_ro_map_lock); err = set_syncpt_ro_map_gpu_va_locked(vm); @@ -146,6 +147,9 @@ int vgpu_gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, *base_gpuva = vm->syncpt_ro_map_gpu_va; *sync_size = g->syncpt_size; + tmp = g->syncpt_size ? (g->syncpt_unit_size / g->syncpt_size) : 0U; + *num_syncpoints = (tmp <= U32_MAX) ? tmp : U32_MAX; + return 0; } #endif /* CONFIG_TEGRA_GK20A_NVHOST */ diff --git a/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.h b/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.h index aca50818f..4e2c9a170 100644 --- a/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.h +++ b/drivers/gpu/nvgpu/hal/vgpu/sync/syncpt_cmdbuf_gv11b_vgpu.h @@ -35,5 +35,5 @@ int vgpu_gv11b_syncpt_alloc_buf(struct nvgpu_channel *c, void vgpu_gv11b_syncpt_free_buf(struct nvgpu_channel *c, struct nvgpu_mem *syncpt_buf); int vgpu_gv11b_syncpt_get_sync_ro_map(struct vm_gk20a *vm, - u64 *base_gpuva, u32 *sync_size); + u64 *base_gpuva, u32 *sync_size, u32 *num_syncpoints); #endif /* NVGPU_SYNCPT_CMDBUF_GV11B_VGPU_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/sync.h b/drivers/gpu/nvgpu/include/nvgpu/gops/sync.h index e4784eb08..34be0fff8 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/sync.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/sync.h @@ -44,8 +44,9 @@ struct gops_sync_syncpt { * @param vm [in] VM area for channel. * @param base_gpu [out] Base GPU VA for mapped * syncpoint aperture. - * @param sync_size [out] Size of syncpoint aperture - * in bytes. + * @param sync_size [out] Size per syncpoint in bytes. + * @param num_syncpoints [out] Number of syncpoints in the + * aperture. * * Map syncpoint aperture in GPU virtual memory as read-only: * - Acquire syncpoint read-only map lock. @@ -53,12 +54,14 @@ struct gops_sync_syncpt { * if not already mapped. Map as read-only. * - Release syncpoint read-only map lock. * + * The syncpoint shim mapping size is sync_size * num_syncpoints. + * * @return 0 in case of success, < 0 in case of failure. * @retval -ENOMEM if syncpoint aperture could not be * mapped to GPU virtual memory. */ int (*get_sync_ro_map)(struct vm_gk20a *vm, - u64 *base_gpuva, u32 *sync_size); + u64 *base_gpuva, u32 *sync_size, u32 *num_syncpoints); /** @cond DOXYGEN_SHOULD_SKIP_THIS */ int (*alloc_buf)(struct nvgpu_channel *c, diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_as.c b/drivers/gpu/nvgpu/os/linux/ioctl_as.c index 0b0b69bce..981a1d58d 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_as.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_as.c @@ -281,6 +281,7 @@ static int nvgpu_as_ioctl_get_sync_ro_map( struct gk20a *g = gk20a_from_vm(vm); u64 base_gpuva; u32 sync_size; + u32 num_syncpoints; int err = 0; if (g->ops.sync.syncpt.get_sync_ro_map == NULL) @@ -289,12 +290,14 @@ static int nvgpu_as_ioctl_get_sync_ro_map( if (!nvgpu_has_syncpoints(g)) return -EINVAL; - err = g->ops.sync.syncpt.get_sync_ro_map(vm, &base_gpuva, &sync_size); + err = g->ops.sync.syncpt.get_sync_ro_map(vm, &base_gpuva, &sync_size, + &num_syncpoints); if (err) return err; args->base_gpuva = base_gpuva; args->sync_size = sync_size; + args->num_syncpoints = num_syncpoints; return err; #else diff --git a/include/uapi/linux/nvgpu-as.h b/include/uapi/linux/nvgpu-as.h index ec56abb63..675f3c316 100644 --- a/include/uapi/linux/nvgpu-as.h +++ b/include/uapi/linux/nvgpu-as.h @@ -375,7 +375,7 @@ struct nvgpu_as_map_buffer_batch_args { struct nvgpu_as_get_sync_ro_map_args { __u64 base_gpuva; __u32 sync_size; - __u32 padding; + __u32 num_syncpoints; }; /* diff --git a/userspace/units/sync/nvgpu-sync.c b/userspace/units/sync/nvgpu-sync.c index 721e08521..67c5b91d4 100644 --- a/userspace/units/sync/nvgpu-sync.c +++ b/userspace/units/sync/nvgpu-sync.c @@ -341,6 +341,7 @@ int test_sync_get_ro_map(struct unit_module *m, struct gk20a *g, void *args) { u64 base_gpuva = 0U; u32 sync_size = 0U; + u32 num_syncpoints = 0U; u32 branches; int err = 0; @@ -366,7 +367,7 @@ int test_sync_get_ro_map(struct unit_module *m, struct gk20a *g, void *args) unit_info(m, "%s branch: %s\n", __func__, f_sync_get_ro_map[branches]); err = g->ops.sync.syncpt.get_sync_ro_map(ch->vm, - &base_gpuva, &sync_size); + &base_gpuva, &sync_size, &num_syncpoints); if (branches < F_SYNC_GET_RO_MAP_FAIL) { if(err != 0) {