From 6509bb49da19ba9b19e3df64e473b01d54fd310d Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Tue, 30 Apr 2019 15:11:31 +0530 Subject: gpu: nvgpu: protect recovery with engines_reset_mutex Rename gr_reset_mutex to engines_reset_mutex and acquire it before initiating recovery. Recovery running in parallel with engine reset is not recommended. On hitting engine reset, h/w drops the ctxsw_status to INVALID in fifo_engine_status register. Also while the engine is held in reset h/w passes busy/idle straight through. fifo_engine_status registers are correct in that there is no context switch outstanding as the CTXSW is aborted when reset is asserted. Use deferred_reset_mutex to protect deferred_reset_pending variable If deferred_reset_pending is true then acquire engines_reset_mutex and call gk20a_fifo_deferred_reset. gk20a_fifo_deferred_reset would also check the value of deferred_reset_pending before initiating reset process Bug 2092051 Bug 2429295 Bug 2484211 Bug 1890287 Change-Id: I47de669a6203e0b2e9a8237ec4e4747339b9837c Signed-off-by: Seema Khowala Reviewed-on: https://git-master.nvidia.com/r/2022373 Signed-off-by: Debarshi Dutta (cherry-picked from cb91bf1e13740023903282d1c2271d9154e940ba in dev-main) Reviewed-on: https://git-master.nvidia.com/r/2024901 GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/nvgpu/common/fifo/channel.c') diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index d30b8ded..4bea032a 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -308,6 +308,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) struct dbg_session_data *session_data, *tmp_s; struct dbg_session_channel_data *ch_data, *tmp; int err; + bool deferred_reset_pending; nvgpu_log_fn(g, " "); @@ -381,17 +382,17 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) /* if engine reset was deferred, perform it now */ nvgpu_mutex_acquire(&f->deferred_reset_mutex); - if (g->fifo.deferred_reset_pending) { + deferred_reset_pending = g->fifo.deferred_reset_pending; + nvgpu_mutex_release(&f->deferred_reset_mutex); + + if (deferred_reset_pending) { nvgpu_log(g, gpu_dbg_intr | gpu_dbg_gpu_dbg, "engine reset was" - " deferred, running now"); - /* if lock is already taken, a reset is taking place - so no need to repeat */ - if (nvgpu_mutex_tryacquire(&g->fifo.gr_reset_mutex)) { - gk20a_fifo_deferred_reset(g, ch); - nvgpu_mutex_release(&g->fifo.gr_reset_mutex); - } + " deferred, running now"); + nvgpu_mutex_acquire(&g->fifo.engines_reset_mutex); + gk20a_fifo_deferred_reset(g, ch); + nvgpu_mutex_release(&g->fifo.engines_reset_mutex); } - nvgpu_mutex_release(&f->deferred_reset_mutex); + if (!gk20a_channel_as_bound(ch)) { goto unbind; -- cgit v1.2.2