mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 02:52:51 +03:00
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 <dnibade@nvidia.com> Reviewed-on: http://git-master/r/921290 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Terje Bergstrom
parent
54f76d1ac6
commit
c4ac1ed369
@@ -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 */
|
||||
|
||||
@@ -195,7 +195,7 @@ void gk20a_channel_close(struct channel_gk20a *ch);
|
||||
bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch,
|
||||
u32 timeout_delta_ms);
|
||||
void gk20a_disable_channel(struct channel_gk20a *ch);
|
||||
void gk20a_channel_abort(struct channel_gk20a *ch);
|
||||
void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt);
|
||||
int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout);
|
||||
void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error);
|
||||
void gk20a_channel_semaphore_wakeup(struct gk20a *g);
|
||||
|
||||
@@ -894,7 +894,7 @@ void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid)
|
||||
mutex_lock(&tsg->ch_list_lock);
|
||||
list_for_each_entry(ch, &tsg->ch_list, ch_entry) {
|
||||
if (gk20a_channel_get(ch)) {
|
||||
gk20a_channel_abort(ch);
|
||||
gk20a_channel_abort(ch, false);
|
||||
gk20a_channel_put(ch);
|
||||
}
|
||||
}
|
||||
@@ -1064,7 +1064,7 @@ static bool gk20a_fifo_handle_mmu_fault(
|
||||
if (referenced_channel) {
|
||||
if (!g->fifo.deferred_reset_pending)
|
||||
verbose = gk20a_fifo_set_ctx_mmu_error_ch(g, ch);
|
||||
gk20a_channel_abort(ch);
|
||||
gk20a_channel_abort(ch, false);
|
||||
gk20a_channel_put(ch);
|
||||
} else {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
@@ -1217,7 +1217,7 @@ void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose)
|
||||
struct channel_gk20a *ch = &g->fifo.channel[hw_chid];
|
||||
|
||||
if (gk20a_channel_get(ch)) {
|
||||
gk20a_channel_abort(ch);
|
||||
gk20a_channel_abort(ch, false);
|
||||
|
||||
if (gk20a_fifo_set_ctx_mmu_error_ch(g, ch))
|
||||
gk20a_debug_dump(g->dev);
|
||||
|
||||
@@ -566,7 +566,7 @@ int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info)
|
||||
break;
|
||||
case TEGRA_VGPU_FIFO_INTR_MMU_FAULT:
|
||||
vgpu_fifo_set_ctx_mmu_error(g, ch);
|
||||
gk20a_channel_abort(ch);
|
||||
gk20a_channel_abort(ch, false);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
|
||||
Reference in New Issue
Block a user