From 20a4080be09b91b79071e3a7d8d5a87259d10a83 Mon Sep 17 00:00:00 2001 From: Philip Elcan Date: Mon, 2 Mar 2020 16:37:25 -0500 Subject: [PATCH] gpu: nvgpu: quiesce: stop thread gracefully Previously, nvgpu_sw_quiesce_remove_support() stopped the quiesce thread abruptly with nvgpu_thread_stop(), which could mean the thread was killed while still waiting on the cond. Then when the cond was destroyed, there may be an error since the underlying implementation may think there is still a thread waiting (such as the Posix implementation). Change nvgpu_sw_quiesce_remove_support() to use nvgpu_thread_stop_graceful() and signal the cond in the callback after the thread is marked to be stopped. The quiesce thread will then wake up from the cond wait and see the thread should stop. JIRA NVGPU-4987 Change-Id: I29322d7867acc33a91092016c540e00bb1ae945a Signed-off-by: Philip Elcan Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2306024 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: svc-mobile-cert Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Thomas Fleury Reviewed-by: Alex Waterman Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/init/nvgpu_init.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index 441364d63..06b0ee6ae 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -145,12 +145,28 @@ static int nvgpu_sw_quiesce_init_support(struct gk20a *g) return 0; } +#ifndef CONFIG_NVGPU_RECOVERY +static void nvgpu_sw_quiesce_thread_stop_fn(void *data) +{ + struct gk20a *g = data; + + /* + * If the thread is still waiting on the cond, + * nvgpu_thread_should_stop() will return true, and the thread will + * exit. + */ + nvgpu_cond_signal(&g->sw_quiesce_cond); +} +#endif + void nvgpu_sw_quiesce_remove_support(struct gk20a *g) { #ifndef CONFIG_NVGPU_RECOVERY if (g->sw_quiesce_init_done) { nvgpu_bug_unregister_cb(&g->sw_quiesce_bug_cb); - nvgpu_thread_stop(&g->sw_quiesce_thread); + nvgpu_thread_stop_graceful(&g->sw_quiesce_thread, + nvgpu_sw_quiesce_thread_stop_fn, + g); nvgpu_cond_destroy(&g->sw_quiesce_cond); g->sw_quiesce_init_done = false; }