diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 32 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 16 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | 2 |
4 files changed, 34 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index b1d9fa55..3159f026 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -443,21 +443,11 @@ int gk20a_disable_channel_tsg(struct gk20a *g, struct channel_gk20a *ch) | |||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | 445 | ||
446 | void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) | 446 | void gk20a_channel_abort_clean_up(struct channel_gk20a *ch) |
447 | { | 447 | { |
448 | struct channel_gk20a_job *job, *n; | 448 | struct channel_gk20a_job *job, *n; |
449 | bool released_job_semaphore = false; | 449 | bool released_job_semaphore = false; |
450 | 450 | ||
451 | gk20a_dbg_fn(""); | ||
452 | |||
453 | /* make sure new kickoffs are prevented */ | ||
454 | ch->has_timedout = true; | ||
455 | |||
456 | ch->g->ops.fifo.disable_channel(ch); | ||
457 | |||
458 | if (channel_preempt) | ||
459 | gk20a_fifo_preempt(ch->g, ch); | ||
460 | |||
461 | /* ensure no fences are pending */ | 451 | /* ensure no fences are pending */ |
462 | mutex_lock(&ch->sync_lock); | 452 | mutex_lock(&ch->sync_lock); |
463 | if (ch->sync) | 453 | if (ch->sync) |
@@ -481,6 +471,24 @@ void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) | |||
481 | gk20a_channel_update(ch, 0); | 471 | gk20a_channel_update(ch, 0); |
482 | } | 472 | } |
483 | 473 | ||
474 | void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt) | ||
475 | { | ||
476 | gk20a_dbg_fn(""); | ||
477 | |||
478 | if (gk20a_is_channel_marked_as_tsg(ch)) | ||
479 | return gk20a_fifo_abort_tsg(ch->g, ch->tsgid, channel_preempt); | ||
480 | |||
481 | /* make sure new kickoffs are prevented */ | ||
482 | ch->has_timedout = true; | ||
483 | |||
484 | ch->g->ops.fifo.disable_channel(ch); | ||
485 | |||
486 | if (channel_preempt) | ||
487 | ch->g->ops.fifo.preempt_channel(ch->g, ch->hw_chid); | ||
488 | |||
489 | gk20a_channel_abort_clean_up(ch); | ||
490 | } | ||
491 | |||
484 | int gk20a_wait_channel_idle(struct channel_gk20a *ch) | 492 | int gk20a_wait_channel_idle(struct channel_gk20a *ch) |
485 | { | 493 | { |
486 | bool channel_idle = false; | 494 | bool channel_idle = false; |
@@ -1714,7 +1722,7 @@ static void gk20a_channel_timeout_handler(struct work_struct *work) | |||
1714 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; | 1722 | struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid]; |
1715 | 1723 | ||
1716 | gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg); | 1724 | gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg); |
1717 | gk20a_fifo_abort_tsg(g, ch->tsgid); | 1725 | gk20a_fifo_abort_tsg(g, ch->tsgid, false); |
1718 | } else { | 1726 | } else { |
1719 | gk20a_fifo_set_ctx_mmu_error_ch(g, ch); | 1727 | gk20a_fifo_set_ctx_mmu_error_ch(g, ch); |
1720 | gk20a_channel_abort(ch, false); | 1728 | gk20a_channel_abort(ch, false); |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index b1355f92..29a13d24 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -212,6 +212,7 @@ bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, | |||
212 | u32 timeout_delta_ms); | 212 | u32 timeout_delta_ms); |
213 | void gk20a_disable_channel(struct channel_gk20a *ch); | 213 | void gk20a_disable_channel(struct channel_gk20a *ch); |
214 | void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt); | 214 | void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt); |
215 | void gk20a_channel_abort_clean_up(struct channel_gk20a *ch); | ||
215 | int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout); | 216 | int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout); |
216 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); | 217 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); |
217 | void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events); | 218 | void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index f8382afe..17efe5ca 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -953,15 +953,23 @@ bool gk20a_fifo_set_ctx_mmu_error_tsg(struct gk20a *g, | |||
953 | return ret; | 953 | return ret; |
954 | } | 954 | } |
955 | 955 | ||
956 | void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid) | 956 | void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid, bool preempt) |
957 | { | 957 | { |
958 | struct tsg_gk20a *tsg = &g->fifo.tsg[tsgid]; | 958 | struct tsg_gk20a *tsg = &g->fifo.tsg[tsgid]; |
959 | struct channel_gk20a *ch; | 959 | struct channel_gk20a *ch; |
960 | 960 | ||
961 | gk20a_dbg_fn(""); | ||
962 | |||
963 | gk20a_disable_tsg(tsg); | ||
964 | |||
965 | if (preempt) | ||
966 | g->ops.fifo.preempt_tsg(g, tsgid); | ||
967 | |||
961 | mutex_lock(&tsg->ch_list_lock); | 968 | mutex_lock(&tsg->ch_list_lock); |
962 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { | 969 | list_for_each_entry(ch, &tsg->ch_list, ch_entry) { |
963 | if (gk20a_channel_get(ch)) { | 970 | if (gk20a_channel_get(ch)) { |
964 | gk20a_channel_abort(ch, false); | 971 | ch->has_timedout = true; |
972 | gk20a_channel_abort_clean_up(ch); | ||
965 | gk20a_channel_put(ch); | 973 | gk20a_channel_put(ch); |
966 | } | 974 | } |
967 | } | 975 | } |
@@ -1129,7 +1137,7 @@ static bool gk20a_fifo_handle_mmu_fault( | |||
1129 | verbose = | 1137 | verbose = |
1130 | gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg); | 1138 | gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg); |
1131 | 1139 | ||
1132 | gk20a_fifo_abort_tsg(g, tsg->tsgid); | 1140 | gk20a_fifo_abort_tsg(g, tsg->tsgid, false); |
1133 | 1141 | ||
1134 | /* put back the ref taken early above */ | 1142 | /* put back the ref taken early above */ |
1135 | if (referenced_channel) | 1143 | if (referenced_channel) |
@@ -1324,7 +1332,7 @@ void gk20a_fifo_recover_tsg(struct gk20a *g, u32 tsgid, bool verbose) | |||
1324 | if (gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg)) | 1332 | if (gk20a_fifo_set_ctx_mmu_error_tsg(g, tsg)) |
1325 | gk20a_debug_dump(g->dev); | 1333 | gk20a_debug_dump(g->dev); |
1326 | 1334 | ||
1327 | gk20a_fifo_abort_tsg(g, tsgid); | 1335 | gk20a_fifo_abort_tsg(g, tsgid, false); |
1328 | } | 1336 | } |
1329 | 1337 | ||
1330 | gr_gk20a_enable_ctxsw(g); | 1338 | gr_gk20a_enable_ctxsw(g); |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h index 986db4b1..5fb5f550 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h | |||
@@ -207,7 +207,7 @@ u32 gk20a_fifo_get_failing_engine_data(struct gk20a *g, | |||
207 | int *__id, bool *__is_tsg); | 207 | int *__id, bool *__is_tsg); |
208 | bool gk20a_fifo_set_ctx_mmu_error_tsg(struct gk20a *g, | 208 | bool gk20a_fifo_set_ctx_mmu_error_tsg(struct gk20a *g, |
209 | struct tsg_gk20a *tsg); | 209 | struct tsg_gk20a *tsg); |
210 | void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid); | 210 | void gk20a_fifo_abort_tsg(struct gk20a *g, u32 tsgid, bool preempt); |
211 | bool gk20a_fifo_set_ctx_mmu_error_ch(struct gk20a *g, | 211 | bool gk20a_fifo_set_ctx_mmu_error_ch(struct gk20a *g, |
212 | struct channel_gk20a *ch); | 212 | struct channel_gk20a *ch); |
213 | 213 | ||