From 2e3c3aada6f60a4989ba87adc3eb3a5a4f89f9a7 Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Wed, 18 Aug 2021 10:44:53 +0530 Subject: [PATCH] gpu: nvgpu: fix deinit of GR Existing implementation of GR de-init doesn't account for multiple instances of struct nvgpu_gr. As a fix, below changes are added. 1) nvgpu_gr_free is unified for VGPU as well as native. 2) All the GR instances are freed. 3) Appropriate NULL checks are added when freeing GR memories. 4) 2D, 3D, I2M and ZBC etc are explicitely disabled when MIG is set. 5) In ioctl_ctrl, checks are added to not return error when zbc is NULL for VGPU as requests are rerouted to RMserver. Jira NVGPU-6920 Change-Id: Icaa40f88f523c2cdbfe3a4fd6a55681ea7a83d12 Signed-off-by: Debarshi Dutta Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2578500 Reviewed-by: svc_kernel_abi Reviewed-by: Vijayakumar Subbu Reviewed-by: Dinesh T Reviewed-by: Seshendra Gadagottu Reviewed-by: mobile promotions Tested-by: Antony Clince Alex Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/common/gr/global_ctx.c | 4 +- drivers/gpu/nvgpu/common/gr/gr.c | 47 ++++++++++++++-------- drivers/gpu/nvgpu/common/gr/gr_config.c | 3 ++ drivers/gpu/nvgpu/common/init/nvgpu_init.c | 4 ++ drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c | 16 -------- drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 2 +- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 12 ++++++ 7 files changed, 54 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/global_ctx.c b/drivers/gpu/nvgpu/common/gr/global_ctx.c index 9294bbc28..259516e8a 100644 --- a/drivers/gpu/nvgpu/common/gr/global_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/global_ctx.c @@ -67,7 +67,9 @@ nvgpu_gr_global_ctx_desc_alloc(struct gk20a *g) void nvgpu_gr_global_ctx_desc_free(struct gk20a *g, struct nvgpu_gr_global_ctx_buffer_desc *desc) { - nvgpu_kfree(g, desc); + if (desc != NULL) { + nvgpu_kfree(g, desc); + } } diff --git a/drivers/gpu/nvgpu/common/gr/gr.c b/drivers/gpu/nvgpu/common/gr/gr.c index bc428c084..025e734a4 100644 --- a/drivers/gpu/nvgpu/common/gr/gr.c +++ b/drivers/gpu/nvgpu/common/gr/gr.c @@ -305,29 +305,31 @@ out: static void gr_remove_support(struct gk20a *g) { - struct nvgpu_gr *gr = g->gr; + struct nvgpu_gr *gr = NULL; + u32 i; nvgpu_log_fn(g, " "); - nvgpu_gr_global_ctx_buffer_free(g, gr->global_ctx_buffer); - nvgpu_gr_global_ctx_desc_free(g, gr->global_ctx_buffer); - - nvgpu_gr_ctx_desc_free(g, gr->gr_ctx_desc); - - nvgpu_gr_config_deinit(g, gr->config); - nvgpu_netlist_deinit_ctx_vars(g); -#ifdef CONFIG_NVGPU_DEBUGGER - nvgpu_gr_hwpm_map_deinit(g, gr->hwpm_map); -#endif + for (i = 0U; i < g->num_gr_instances; i++) { + gr = &g->gr[i]; -#ifdef CONFIG_NVGPU_GRAPHICS - nvgpu_gr_zbc_deinit(g, gr->zbc); - nvgpu_gr_zcull_deinit(g, gr->zcull); -#endif /* CONFIG_NVGPU_GRAPHICS */ + nvgpu_gr_global_ctx_buffer_free(g, gr->global_ctx_buffer); + nvgpu_gr_global_ctx_desc_free(g, gr->global_ctx_buffer); + gr->global_ctx_buffer = NULL; - nvgpu_gr_obj_ctx_deinit(g, gr->golden_image); + nvgpu_gr_ctx_desc_free(g, gr->gr_ctx_desc); + gr->gr_ctx_desc = NULL; + + #ifdef CONFIG_NVGPU_DEBUGGER + nvgpu_gr_hwpm_map_deinit(g, gr->hwpm_map); + gr->hwpm_map = NULL; + #endif + + nvgpu_gr_obj_ctx_deinit(g, gr->golden_image); + gr->golden_image = NULL; + } nvgpu_gr_free(g); } @@ -522,6 +524,9 @@ static int gr_init_setup_sw(struct gk20a *g, struct nvgpu_gr *gr) if (err != 0) { goto clean_up; } + } else { + gr->zbc = NULL; + gr->zcull = NULL; } #endif /* CONFIG_NVGPU_GRAPHICS */ @@ -1026,11 +1031,21 @@ void nvgpu_gr_free(struct gk20a *g) for (i = 0U; i < g->num_gr_instances; i++) { gr = &g->gr[i]; + nvgpu_gr_config_deinit(g, gr->config); + gr->config = NULL; + nvgpu_gr_falcon_remove_support(g, gr->falcon); gr->falcon = NULL; nvgpu_gr_intr_remove_support(g, gr->intr); gr->intr = NULL; + +#ifdef CONFIG_NVGPU_GRAPHICS + nvgpu_gr_zbc_deinit(g, gr->zbc); + nvgpu_gr_zcull_deinit(g, gr->zcull); + gr->zbc = NULL; + gr->zcull = NULL; +#endif /* CONFIG_NVGPU_GRAPHICS */ } nvgpu_kfree(g, g->gr); diff --git a/drivers/gpu/nvgpu/common/gr/gr_config.c b/drivers/gpu/nvgpu/common/gr/gr_config.c index 90c4a9b96..c3c1223cd 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_config.c +++ b/drivers/gpu/nvgpu/common/gr/gr_config.c @@ -692,12 +692,15 @@ void nvgpu_gr_config_deinit(struct gk20a *g, struct nvgpu_gr_config *config) nvgpu_kfree(g, config->map_tiles); #endif nvgpu_kfree(g, config->sm_to_cluster); + config->sm_to_cluster = NULL; #ifdef CONFIG_NVGPU_SM_DIVERSITY if (config->sm_to_cluster_redex_config != NULL) { nvgpu_kfree(g, config->sm_to_cluster_redex_config); config->sm_to_cluster_redex_config = NULL; } #endif + + nvgpu_kfree(g, config); } u32 nvgpu_gr_config_get_max_gpc_count(struct nvgpu_gr_config *config) diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index daba0a4b8..ab01433b6 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -1030,6 +1030,10 @@ int nvgpu_init_gpu_characteristics(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_SUPPORT_I2M, true); nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC, true); } else { + nvgpu_set_enabled(g, NVGPU_SUPPORT_2D, false); + nvgpu_set_enabled(g, NVGPU_SUPPORT_3D, false); + nvgpu_set_enabled(g, NVGPU_SUPPORT_I2M, false); + nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_ZBC_STENCIL, false); nvgpu_set_enabled(g, NVGPU_SUPPORT_PREEMPTION_GFXP, false); } diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c index e57c189ab..6ce56786c 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c @@ -597,22 +597,6 @@ static void vgpu_remove_gr_support(struct gk20a *g) nvgpu_log_fn(gr->g, " "); - nvgpu_kfree(gr->g, gr->config->sm_to_cluster); - gr->config->sm_to_cluster = NULL; - -#ifdef CONFIG_NVGPU_SM_DIVERSITY - if (gr->config->sm_to_cluster_redex_config != NULL) { - nvgpu_kfree(g, gr->config->sm_to_cluster_redex_config); - gr->config->sm_to_cluster_redex_config = NULL; - } -#endif - - nvgpu_gr_config_deinit(gr->g, gr->config); - -#ifdef CONFIG_NVGPU_GRAPHICS - nvgpu_gr_zcull_deinit(gr->g, gr->zcull); -#endif - nvgpu_gr_free(g); } diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 3ecbe82de..6902cd855 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -477,7 +477,7 @@ struct gk20a { /** @cond DOXYGEN_SHOULD_SKIP_THIS */ struct nvgpu_nvlink_dev nvlink; /** @endcond */ - /** Pointer to struct maintaining GR unit's software state. */ + /** Pointer to struct maintaining multiple GR instance's software state. */ struct nvgpu_gr *gr; u32 num_gr_instances; /** Pointer to struct maintaining fbp unit's software state. */ diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index ee8398e9e..d7eb39107 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -1951,12 +1951,18 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg switch (cmd) { #ifdef CONFIG_NVGPU_GRAPHICS case NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE: + if (gr_zcull == NULL) + return -ENODEV; + get_ctx_size_args = (struct nvgpu_gpu_zcull_get_ctx_size_args *)buf; get_ctx_size_args->size = nvgpu_gr_get_ctxsw_zcull_size(g, gr_zcull); break; case NVGPU_GPU_IOCTL_ZCULL_GET_INFO: + if (gr_zcull == NULL) + return -ENODEV; + get_info_args = (struct nvgpu_gpu_zcull_get_info_args *)buf; (void) memset(get_info_args, 0, @@ -1987,6 +1993,9 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg nvgpu_kfree(g, zcull_info); break; case NVGPU_GPU_IOCTL_ZBC_SET_TABLE: + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_ZBC)) + return -ENODEV; + set_table_args = (struct nvgpu_gpu_zbc_set_table_args *)buf; zbc_val = nvgpu_gr_zbc_entry_alloc(g); @@ -2027,6 +2036,9 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg nvgpu_gr_zbc_entry_free(g, zbc_val); break; case NVGPU_GPU_IOCTL_ZBC_QUERY_TABLE: + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_ZBC)) + return -ENODEV; + query_table_args = (struct nvgpu_gpu_zbc_query_table_args *)buf; zbc_tbl = nvgpu_kzalloc(g, sizeof(struct nvgpu_gr_zbc_query_params));