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 <pelcan@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2306024
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Philip Elcan
2020-03-02 16:37:25 -05:00
committed by Alex Waterman
parent 0220409d0f
commit 20a4080be0

View File

@@ -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;
}