From 33ff34887f560449828e79170a2a36a97496eeec Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 1 Aug 2016 17:02:31 +0530 Subject: gpu: nvgpu: fix deferred engine reset sequence We currently store fault_id into fifo.deferred_fault_engines and use that in gk20a_fifo_reset_engine() which is incorrect Also, in deferred engine reset path during channel close, we do not check if channel is loaded on engine or not fix this with below - store engine_id bits into fifo.deferred_fault_engines - define new API gk20a_fifo_deferred_reset() to perform deferred engine reset - get all engines on which channel is loaded with gk20a_fifo_engines_on_id() - for each set bit/engine_id in fifo.deferred_fault_engines, check if channel is loaded on that engine, and if yes, reset the engine Bug 1791696 Change-Id: I1b8b1a9e3aa538fe6903a352aa732b47c95ec7d5 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/1195087 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/gk20a/fifo_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 23a014d7..b025f4d6 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -39,6 +39,7 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, u32 hw_chid, bool add, bool wait_for_finish); +static u32 gk20a_fifo_engines_on_id(struct gk20a *g, u32 id, bool is_tsg); u32 gk20a_fifo_get_engine_ids(struct gk20a *g, u32 engine_id[], u32 engine_id_sz, @@ -1269,6 +1270,42 @@ void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid, bool preempt) mutex_unlock(&tsg->ch_list_lock); } +int gk20a_fifo_deferred_reset(struct gk20a *g, struct channel_gk20a *ch) +{ + u32 engine_id, engines; + + mutex_lock(&g->dbg_sessions_lock); + gr_gk20a_disable_ctxsw(g); + + if (!g->fifo.deferred_reset_pending) + goto clean_up; + + if (gk20a_is_channel_marked_as_tsg(ch)) + engines = gk20a_fifo_engines_on_id(g, ch->tsgid, true); + else + engines = gk20a_fifo_engines_on_id(g, ch->hw_chid, false); + if (!engines) + goto clean_up; + + /* + * If deferred reset is set for an engine, and channel is running + * on that engine, reset it + */ + for_each_set_bit(engine_id, &g->fifo.deferred_fault_engines, 32) { + if (BIT(engine_id) & engines) + gk20a_fifo_reset_engine(g, engine_id); + } + + g->fifo.deferred_fault_engines = 0; + g->fifo.deferred_reset_pending = false; + +clean_up: + gr_gk20a_enable_ctxsw(g); + mutex_unlock(&g->dbg_sessions_lock); + + return 0; +} + static bool gk20a_fifo_handle_mmu_fault( struct gk20a *g, u32 mmu_fault_engines, /* queried from HW if 0 */ @@ -1403,7 +1440,7 @@ static bool gk20a_fifo_handle_mmu_fault( /* check if engine reset should be deferred */ if ((ch || tsg) && gk20a_fifo_should_defer_engine_reset(g, engine_id, &f, fake_fault)) { - g->fifo.deferred_fault_engines = fault_id; + g->fifo.deferred_fault_engines |= BIT(engine_id); /* handled during channel free */ g->fifo.deferred_reset_pending = true; -- cgit v1.2.2