From d01a0249c40217236497728997b9c6ce8619acad Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 5 Oct 2015 13:54:37 +0530 Subject: gpu: nvgpu: cancel all wdt timeouts while handling SCHED errors A SCHED error might cause multiple channels' watchdogs to trigger simultaneously Hence, to avoid this conflict cancel watchdog timeout on all channels before recovering from SCHED errors Also, define API gk20a_channel_timeout_stop_all_channels() to cancel wdt timeout on all channels Bug 200133289 Change-Id: I8324c397891f0a711327b77d0677cd6718af6d01 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/810959 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 15 +++++++++++++++ drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 + drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 6 ++++++ 3 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index e6a39b20..92b4b3de 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -1573,6 +1573,21 @@ static void gk20a_channel_timeout_stop(struct channel_gk20a *ch) mutex_unlock(&ch->timeout.lock); } +void gk20a_channel_timeout_stop_all_channels(struct gk20a *g) +{ + u32 chid; + struct fifo_gk20a *f = &g->fifo; + + for (chid = 0; chid < f->num_channels; chid++) { + struct channel_gk20a *ch = &f->channel[chid]; + + if (gk20a_channel_get(ch)) { + gk20a_channel_timeout_stop(ch); + gk20a_channel_put(ch); + } + } +} + static void gk20a_channel_timeout_handler(struct work_struct *work) { struct channel_gk20a_job *job; diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 20600207..280c50b1 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h @@ -256,4 +256,5 @@ void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch); int channel_gk20a_setup_ramfc(struct channel_gk20a *c, u64 gpfifo_base, u32 gpfifo_entries, u32 flags); void channel_gk20a_enable(struct channel_gk20a *ch); +void gk20a_channel_timeout_stop_all_channels(struct gk20a *g); #endif /* CHANNEL_GK20A_H */ diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index ae36478e..4f3363f2 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -1450,6 +1450,7 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g) struct channel_gk20a *ch = &f->channel[id]; if (is_tsg) { + gk20a_channel_timeout_stop_all_channels(g); gk20a_fifo_recover(g, BIT(engine_id), id, true, true, true); ret = true; @@ -1467,6 +1468,11 @@ static bool gk20a_fifo_handle_sched_error(struct gk20a *g) "fifo sched ctxsw timeout error:" "engine = %u, ch = %d", engine_id, id); gk20a_gr_debug_dump(g->dev); + /* + * Cancel all channels' timeout since SCHED error might + * trigger multiple watchdogs at a time + */ + gk20a_channel_timeout_stop_all_channels(g); gk20a_fifo_recover(g, BIT(engine_id), id, false, true, ch->timeout_debug_dump); ret = true; -- cgit v1.2.2