diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index e6a39b20e..92b4b3def 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 20600207f..280c50b11 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 ae36478e1..4f3363f25 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;