From c4ac1ed369cb5737de10924908d97be9f11ec875 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Thu, 10 Dec 2015 14:28:32 +0530 Subject: gpu: nvgpu: preempt before adjusting fences Current sequence in gk20a_disable_channel() is - disable channel in gk20a_channel_abort() - adjust pending fence in gk20a_channel_abort() - preempt channel But this leads to scenarios where syncpoint has min > max value Hence to fix this, make sequence in gk20a_disable_channel() - disable channel in gk20a_channel_abort() - preempt channel in gk20a_channel_abort() - adjust pending fence in gk20a_channel_abort() If gk20a_channel_abort() is called from other API where preemption is not needed, then use channel_preempt flag and do not preempt channel in those cases Bug 1683059 Change-Id: I4d46d4294cf8597ae5f05f79dfe1b95c4187f2e3 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/921290 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 7ec5ade4..b480c80a 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -392,7 +392,7 @@ void channel_gk20a_disable(struct channel_gk20a *ch) ccsr_channel_enable_clr_true_f()); } -void gk20a_channel_abort(struct channel_gk20a *ch) +void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) { struct channel_gk20a_job *job, *n; bool released_job_semaphore = false; @@ -404,6 +404,9 @@ void gk20a_channel_abort(struct channel_gk20a *ch) ch->g->ops.fifo.disable_channel(ch); + if (channel_preempt) + ch->g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); + /* ensure no fences are pending */ mutex_lock(&ch->sync_lock); if (ch->sync) @@ -455,8 +458,7 @@ int gk20a_wait_channel_idle(struct channel_gk20a *ch) void gk20a_disable_channel(struct channel_gk20a *ch) { - gk20a_channel_abort(ch); - ch->g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); + gk20a_channel_abort(ch, true); channel_gk20a_update_runlist(ch, false); } @@ -1621,7 +1623,7 @@ static void gk20a_channel_timeout_handler(struct work_struct *work) gk20a_fifo_abort_tsg(g, ch->tsgid); } else { gk20a_fifo_set_ctx_mmu_error_ch(g, ch); - gk20a_channel_abort(ch); + gk20a_channel_abort(ch, false); } } else { /* If failing engine, trigger recovery */ -- cgit v1.2.2