From 33740b41b6d0c24502d1bde736e68683f95ac37d Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Tue, 31 Aug 2021 09:54:53 +0530 Subject: [PATCH] gpu: nvgpu: free memory during module removal Following pointers(allocated via Kmalloc/DMA) aren't freed during module removal. struct nvgpu_gr_config -> gpc_tpc_mask_physical struct nvgpu_netlist_vars -> ctxsw_regs.etpc.l struct mm_gk20a -> sysmem_flush struct nvgpu_pmu_pg -> pg_buf SGTable corresponding to VPR secure buffer. Added appropriate free calls. Bug 3364181 Change-Id: I2105c1f3256b1910f0f514d98f0ee3ae2e34aff7 Signed-off-by: Debarshi Dutta Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2586244 Tested-by: mobile promotions Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: svc_kernel_abi Reviewed-by: Seshendra Gadagottu Reviewed-by: Deepak Nibade Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/common/gr/gr_config.c | 1 + drivers/gpu/nvgpu/common/mm/mm.c | 7 +++++++ drivers/gpu/nvgpu/common/netlist/netlist.c | 2 ++ drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c | 3 +++ .../gpu/nvgpu/os/linux/platform_gk20a_tegra.c | 21 ++++++++++++++++++- 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr_config.c b/drivers/gpu/nvgpu/common/gr/gr_config.c index c3c1223cd..503b211f4 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_config.c +++ b/drivers/gpu/nvgpu/common/gr/gr_config.c @@ -201,6 +201,7 @@ static void gr_config_free_mem(struct gk20a *g, #endif nvgpu_kfree(g, config->gpc_tpc_mask); nvgpu_kfree(g, config->gpc_tpc_count); + nvgpu_kfree(g, config->gpc_tpc_mask_physical); } static bool gr_config_alloc_struct_mem(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/common/mm/mm.c b/drivers/gpu/nvgpu/common/mm/mm.c index 5dea4918d..4b225d2f9 100644 --- a/drivers/gpu/nvgpu/common/mm/mm.c +++ b/drivers/gpu/nvgpu/common/mm/mm.c @@ -115,6 +115,11 @@ static int nvgpu_alloc_sysmem_flush(struct gk20a *g) return nvgpu_dma_alloc_sys(g, SZ_4K, &g->mm.sysmem_flush); } +static void nvgpu_free_sysmem_flush(struct gk20a *g) +{ + nvgpu_dma_free(g, &g->mm.sysmem_flush); +} + #ifdef CONFIG_NVGPU_DGPU static void nvgpu_remove_mm_ce_support(struct mm_gk20a *mm) { @@ -172,6 +177,8 @@ static void nvgpu_remove_mm_support(struct mm_gk20a *mm) nvgpu_vm_put(mm->cde.vm); } + nvgpu_free_sysmem_flush(g); + #ifdef CONFIG_NVGPU_SW_SEMAPHORE nvgpu_semaphore_sea_destroy(g); #endif diff --git a/drivers/gpu/nvgpu/common/netlist/netlist.c b/drivers/gpu/nvgpu/common/netlist/netlist.c index 4f6e0a7c5..72fdf061f 100644 --- a/drivers/gpu/nvgpu/common/netlist/netlist.c +++ b/drivers/gpu/nvgpu/common/netlist/netlist.c @@ -794,6 +794,8 @@ void nvgpu_netlist_deinit_ctx_vars(struct gk20a *g) nvgpu_kfree(g, netlist_vars->ctxsw_regs.perf_pma.l); nvgpu_kfree(g, netlist_vars->ctxsw_regs.pm_rop.l); nvgpu_kfree(g, netlist_vars->ctxsw_regs.pm_ucgpc.l); + nvgpu_kfree(g, netlist_vars->ctxsw_regs.etpc.l); + #if defined(CONFIG_NVGPU_NON_FUSA) nvgpu_kfree(g, netlist_vars->ctxsw_regs.sys_compute.l); nvgpu_kfree(g, netlist_vars->ctxsw_regs.gpc_compute.l); diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c index baaf08da3..64e141cd1 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c @@ -912,6 +912,9 @@ void nvgpu_pmu_pg_deinit(struct gk20a *g, struct nvgpu_pmu *pmu, if (nvgpu_mem_is_valid(&pg->seq_buf)) { nvgpu_dma_unmap_free(vm, &pg->seq_buf); } + if (nvgpu_mem_is_valid(&pg->pg_buf)) { + nvgpu_dma_unmap_free(vm, &pg->pg_buf); + } nvgpu_mutex_destroy(&pg->elpg_mutex); nvgpu_mutex_destroy(&pg->pg_mutex); nvgpu_kfree(g, pg); diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c index 279b303df..0597e93be 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a_tegra.c @@ -116,6 +116,25 @@ static void gk20a_tegra_secure_page_destroy(struct gk20a *g, secure_buffer->destroy = NULL; } +static void gk20a_free_secure_buffer(struct gk20a *g, + struct nvgpu_mem *mem) +{ + if (!nvgpu_mem_is_valid(mem)) + return; + + if (mem->priv.sgt != NULL) { + sg_free_table(mem->priv.sgt); + } + + nvgpu_kfree(g, mem->priv.sgt); + mem->priv.sgt = NULL; + + mem->size = 0; + mem->aligned_size = 0; + mem->aperture = APERTURE_INVALID; + +} + static int gk20a_tegra_secure_alloc(struct gk20a *g, struct nvgpu_mem *desc_mem, size_t size, global_ctx_mem_destroy_fn *destroy) @@ -156,7 +175,7 @@ static int gk20a_tegra_secure_alloc(struct gk20a *g, /* This bypasses SMMU for VPR during gmmu_map. */ sg_dma_address(sgt->sgl) = 0; - *destroy = NULL; + *destroy = gk20a_free_secure_buffer; desc_mem->priv.sgt = sgt; desc_mem->size = size;