From 5db14f3bfb7de533843716430bc8df93aa546335 Mon Sep 17 00:00:00 2001 From: Atul Anand Date: Tue, 29 Nov 2022 14:47:53 -0800 Subject: [PATCH] nvgpu: Fix pm resource release sequence The memory leak issue was due to nvgpu_profiler_unbind_context() calling nvgpu_profiler_pm_resource_release() for all resources which clears the flag required by nvgpu_profiler_free_pma_stream() to release the memory for perf_buf instance block. Fixing this issue by splitting nvgpu_profiler_unbind_context() to release all the pm resources at a later time separately. Bug 3510455 Change-Id: Ibab8d071693e600c46f7e7f16575e36e6f62af3c Signed-off-by: atanand Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2825013 Reviewed-by: svcacv Reviewed-by: Dinesh T Reviewed-by: Vaibhav Kachore GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/common/fifo/tsg.c | 10 +++++++- drivers/gpu/nvgpu/common/profiler/profiler.c | 25 ++++++++++++-------- drivers/gpu/nvgpu/include/nvgpu/profiler.h | 1 + 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 5e6adb9ff..8fdd7f33f 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -1397,6 +1397,10 @@ struct nvgpu_tsg *nvgpu_tsg_open(struct gk20a *g, pid_t pid) void nvgpu_tsg_release_common(struct gk20a *g, struct nvgpu_tsg *tsg) { +#ifdef CONFIG_NVGPU_PROFILER + struct nvgpu_profiler_object *prof; +#endif + if (g->ops.tsg.release != NULL) { g->ops.tsg.release(tsg); } @@ -1416,7 +1420,11 @@ void nvgpu_tsg_release_common(struct gk20a *g, struct nvgpu_tsg *tsg) #ifdef CONFIG_NVGPU_PROFILER if (tsg->prof != NULL) { - nvgpu_profiler_unbind_context(tsg->prof); + /* save prof here as tsg pointer will be cleared in unbind */ + prof = tsg->prof; + nvgpu_profiler_unbind_context(prof); + nvgpu_profiler_free_pma_stream(prof); + nvgpu_profiler_pm_resource_release_all(prof); } #endif diff --git a/drivers/gpu/nvgpu/common/profiler/profiler.c b/drivers/gpu/nvgpu/common/profiler/profiler.c index 2396676eb..180ffc4ab 100644 --- a/drivers/gpu/nvgpu/common/profiler/profiler.c +++ b/drivers/gpu/nvgpu/common/profiler/profiler.c @@ -89,6 +89,7 @@ void nvgpu_profiler_free(struct nvgpu_profiler_object *prof) nvgpu_profiler_unbind_context(prof); nvgpu_profiler_free_pma_stream(prof); + nvgpu_profiler_pm_resource_release_all(prof); nvgpu_list_del(&prof->prof_obj_entry); prof->gpu_instance_id = 0U; @@ -123,11 +124,24 @@ int nvgpu_profiler_bind_context(struct nvgpu_profiler_object *prof, return 0; } +void nvgpu_profiler_pm_resource_release_all(struct nvgpu_profiler_object *prof) +{ + int i; + + for (i = 0; i < NVGPU_PROFILER_PM_RESOURCE_TYPE_COUNT; i++) { + if (prof->reserved[i]) { + nvgpu_warn(NULL, + "Releasing reserved resource %u for handle %u", + i, prof->prof_handle); + nvgpu_profiler_pm_resource_release(prof, i); + } + } +} + int nvgpu_profiler_unbind_context(struct nvgpu_profiler_object *prof) { struct gk20a *g = prof->g; struct nvgpu_tsg *tsg = prof->tsg; - int i; if (prof->bound) { nvgpu_warn(g, "Unbinding resources for handle %u", @@ -135,15 +149,6 @@ int nvgpu_profiler_unbind_context(struct nvgpu_profiler_object *prof) nvgpu_profiler_unbind_pm_resources(prof); } - for (i = 0; i < NVGPU_PROFILER_PM_RESOURCE_TYPE_COUNT; i++) { - if (prof->reserved[i]) { - nvgpu_warn(g, "Releasing reserved resource %u for handle %u", - i, prof->prof_handle); - nvgpu_profiler_pm_resource_release(prof, - (enum nvgpu_profiler_pm_resource_type)i); - } - } - if (!prof->context_init) { return -EINVAL; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/profiler.h b/drivers/gpu/nvgpu/include/nvgpu/profiler.h index 21193f29b..aee2daab0 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/profiler.h +++ b/drivers/gpu/nvgpu/include/nvgpu/profiler.h @@ -146,6 +146,7 @@ int nvgpu_profiler_pm_resource_reserve(struct nvgpu_profiler_object *prof, enum nvgpu_profiler_pm_resource_type pm_resource); int nvgpu_profiler_pm_resource_release(struct nvgpu_profiler_object *prof, enum nvgpu_profiler_pm_resource_type pm_resource); +void nvgpu_profiler_pm_resource_release_all(struct nvgpu_profiler_object *prof); int nvgpu_profiler_bind_hwpm(struct gk20a *g, u32 gr_instance_id,