From db089a73a586b34e6266504925b29eea8628673e Mon Sep 17 00:00:00 2001 From: Shashank Singh Date: Thu, 28 Dec 2017 11:52:14 +0530 Subject: gpu: nvgpu: add refcounting for ctxsw disable/enable ctxsw disable could be called recursively for RM server. Suspend contexts disables ctxsw at the beginning, then call tsg disable and preempt. If preempt timeout happens, it goes to recovery path, which will try to disable ctxsw again. More details on Bug 200331110. Jira VQRM-2982 Change-Id: I4659c842ae73ed59be51ae65b25366f24abcaf22 Signed-off-by: Shashank Singh Signed-off-by: Richard Zhao Reviewed-on: https://git-master.nvidia.com/r/1671716 Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Sourab Gupta Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 61975106..8a3f98af 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -616,22 +616,39 @@ static int gr_gk20a_ctrl_ctxsw(struct gk20a *g, u32 fecs_method, u32 *ret) .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); } -/* Stop processing (stall) context switches at FECS. - * The caller must hold the dbg_sessions_lock, else if mutliple stop methods - * are sent to the ucode in sequence, it can get into an undefined state. */ +/* Stop processing (stall) context switches at FECS. */ int gr_gk20a_disable_ctxsw(struct gk20a *g) { + int err = 0; + gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); - return gr_gk20a_ctrl_ctxsw(g, - gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); + + nvgpu_mutex_acquire(&g->ctxsw_disable_lock); + g->ctxsw_disable_count++; + if (g->ctxsw_disable_count == 1) + err = gr_gk20a_ctrl_ctxsw(g, + gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); + nvgpu_mutex_release(&g->ctxsw_disable_lock); + + return err; } /* Start processing (continue) context switches at FECS */ int gr_gk20a_enable_ctxsw(struct gk20a *g) { + int err = 0; + gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); - return gr_gk20a_ctrl_ctxsw(g, - gr_fecs_method_push_adr_start_ctxsw_v(), NULL); + + nvgpu_mutex_acquire(&g->ctxsw_disable_lock); + g->ctxsw_disable_count--; + WARN_ON(g->ctxsw_disable_count < 0); + if (g->ctxsw_disable_count == 0) + err = gr_gk20a_ctrl_ctxsw(g, + gr_fecs_method_push_adr_start_ctxsw_v(), NULL); + nvgpu_mutex_release(&g->ctxsw_disable_lock); + + return err; } int gr_gk20a_halt_pipe(struct gk20a *g) -- cgit v1.2.2