From d70c9a708be345152b8a8096e18e57a5f7a63b1b Mon Sep 17 00:00:00 2001 From: Martin Radev Date: Mon, 8 May 2023 19:25:57 +0300 Subject: [PATCH] gpu: nvgpu: expose local-to-logical/physical GPC mappings Expose the local-to-logical/physical GPC mappings for devtools needs. Bug 3944943 Change-Id: I2aa69ccef19627d41f3e2b8dcc9235401ae1f782 Signed-off-by: Martin Radev Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2900289 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 76 +++++++++++++++++++++++++ include/uapi/linux/nvgpu-ctrl.h | 36 +++++++++++- 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index ce0679dca..4bd3c58cb 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -778,6 +778,74 @@ clean_up: return err; } +static int gk20a_ctrl_get_gpc_local_to_physical_map(struct gk20a *g, struct nvgpu_gr_config *gr_config, + u32 gr_instance_id, struct nvgpu_gpu_get_gpc_physical_map_args *args) +{ + u32 gpc_count; + u32 map_size; + u32 gpc_local_index; + u32 *physical_map; + + gpc_count = nvgpu_gr_config_get_gpc_count(gr_config); + map_size = sizeof(u32) * gpc_count; + + if (map_size != args->map_buf_size) { + return -EINVAL; + } + + physical_map = (u32 *)nvgpu_kzalloc(g, map_size); + if (physical_map == NULL) { + return -ENOMEM; + } + + for (gpc_local_index = 0U; gpc_local_index < gpc_count; ++gpc_local_index) { + physical_map[gpc_local_index] = nvgpu_grmgr_get_gr_gpc_phys_id(g, gr_instance_id, gpc_local_index); + } + + if (copy_to_user((void __user *)(uintptr_t)args->physical_gpc_buf_addr, physical_map, map_size)) { + nvgpu_kfree(g, physical_map); + return -EFAULT; + } + + nvgpu_kfree(g, physical_map); + + return 0; +} + +static int gk20a_ctrl_get_gpc_local_to_logical_map(struct gk20a *g, struct nvgpu_gr_config *gr_config, + u32 gr_instance_id, struct nvgpu_gpu_get_gpc_logical_map_args *args) +{ + u32 gpc_count; + u32 map_size; + u32 gpc_local_index; + u32 *logical_map; + + gpc_count = nvgpu_gr_config_get_gpc_count(gr_config); + map_size = sizeof(u32) * gpc_count; + + if (map_size != args->map_buf_size) { + return -EINVAL; + } + + logical_map = (u32 *)nvgpu_kzalloc(g, map_size); + if (logical_map == NULL) { + return -ENOMEM; + } + + for (gpc_local_index = 0U; gpc_local_index < gpc_count; ++gpc_local_index) { + logical_map[gpc_local_index] = nvgpu_grmgr_get_gr_gpc_logical_id(g, gr_instance_id, gpc_local_index); + } + + if (copy_to_user((void __user *)(uintptr_t)args->logical_gpc_buf_addr, logical_map, map_size)) { + nvgpu_kfree(g, logical_map); + return -EFAULT; + } + + nvgpu_kfree(g, logical_map); + + return 0; +} + static int gk20a_ctrl_get_tpc_masks(struct gk20a *g, struct nvgpu_gr_config *gr_config, struct nvgpu_gpu_get_tpc_masks_args *args) { @@ -2500,6 +2568,14 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg err = gk20a_ctrl_get_tpc_masks(g, gr_config, (struct nvgpu_gpu_get_tpc_masks_args *)buf); break; + case NVGPU_GPU_IOCTL_GET_GPC_LOCAL_TO_PHYSICAL_MAP: + err = gk20a_ctrl_get_gpc_local_to_physical_map(g, gr_config, + gr_instance_id, (struct nvgpu_gpu_get_gpc_physical_map_args *)buf); + break; + case NVGPU_GPU_IOCTL_GET_GPC_LOCAL_TO_LOGICAL_MAP: + err = gk20a_ctrl_get_gpc_local_to_logical_map(g, gr_config, + gr_instance_id, (struct nvgpu_gpu_get_gpc_logical_map_args *)buf); + break; case NVGPU_GPU_IOCTL_GET_FBP_L2_MASKS: err = gk20a_ctrl_get_fbp_l2_masks(g, gpu_instance_id, (struct nvgpu_gpu_get_fbp_l2_masks_args *)buf); diff --git a/include/uapi/linux/nvgpu-ctrl.h b/include/uapi/linux/nvgpu-ctrl.h index dfb0a3f98..7335f866f 100644 --- a/include/uapi/linux/nvgpu-ctrl.h +++ b/include/uapi/linux/nvgpu-ctrl.h @@ -502,6 +502,32 @@ struct nvgpu_gpu_get_tpc_masks_args { __u64 mask_buf_addr; }; +struct nvgpu_gpu_get_gpc_physical_map_args { + /* [in] GPC logical-map-buffer size. It must be + * sizeof(__u32) * fls(gpc_mask) + */ + __u32 map_buf_size; + __u32 reserved; + + /* [out] pointer to array of u32 entries. + * For each entry, index=local gpc index and value=physical gpc index. + */ + __u64 physical_gpc_buf_addr; +}; + +struct nvgpu_gpu_get_gpc_logical_map_args { + /* [in] GPC logical-map-buffer size. It must be + * sizeof(__u32) * fls(gpc_mask) + */ + __u32 map_buf_size; + __u32 reserved; + + /* [out] pointer to array of u32 entries. + * For each entry, index=local gpc index and value=logical gpc index. + */ + __u64 logical_gpc_buf_addr; +}; + struct nvgpu_gpu_open_channel_args { union { __s32 channel_fd; /* deprecated: use out.channel_fd instead */ @@ -1242,11 +1268,15 @@ struct nvgpu_gpu_register_buffer_args { _IOWR(NVGPU_GPU_IOCTL_MAGIC, 40, \ struct nvgpu_gpu_set_deterministic_opts_args) #define NVGPU_GPU_IOCTL_REGISTER_BUFFER \ - _IOWR(NVGPU_GPU_IOCTL_MAGIC, 41, struct nvgpu_gpu_register_buffer_args) + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 41, struct nvgpu_gpu_register_buffer_args) #define NVGPU_GPU_IOCTL_GET_BUFFER_INFO \ - _IOWR(NVGPU_GPU_IOCTL_MAGIC, 42, struct nvgpu_gpu_get_buffer_info_args) + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 42, struct nvgpu_gpu_get_buffer_info_args) +#define NVGPU_GPU_IOCTL_GET_GPC_LOCAL_TO_PHYSICAL_MAP\ + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 43, struct nvgpu_gpu_get_gpc_physical_map_args) +#define NVGPU_GPU_IOCTL_GET_GPC_LOCAL_TO_LOGICAL_MAP\ + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 44, struct nvgpu_gpu_get_gpc_logical_map_args) #define NVGPU_GPU_IOCTL_LAST \ - _IOC_NR(NVGPU_GPU_IOCTL_GET_BUFFER_INFO) + _IOC_NR(NVGPU_GPU_IOCTL_GET_GPC_LOCAL_TO_LOGICAL_MAP) #define NVGPU_GPU_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_gpu_get_cpu_time_correlation_info_args)