summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorLauri Peltonen <lpeltonen@nvidia.com>2014-06-11 05:56:31 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:10 -0400
commitf575bc667649ff1a09aac8ecbe626fde8ea5f2f4 (patch)
treeaf8ef5bd572772e54a97ebfbdb7e693670468c59 /drivers/gpu/nvgpu/gk20a
parentae22cda010d26419476939fa46abf9345c412eff (diff)
gpu: nvgpu: Support semaphore sync when aborting jobs
When aborting jobs on channel error situations, we manually set the channel syncpoint's min == max in gk20a_disable_channel_no_update. Nvhost will notice this manual syncpoint increment, and will call back to gk20a_channel_update, which will clean up the job. With semaphore synchronization, we don't have anybody calling back to gk20a_channel_update, so we need to call it ourselves. Release job semaphores (the equivalent of set_min_eq_max) on gk20a_disable_channel_no_update, and if any semaphores were released, call gk20a_channel_update afterwards. Because we are actually calling gk20a_channel_update in some situations, gk20a_disable_channel_no_update is no longer an appropriate name for the function. Rename it to gk20a_channel_abort. Bug 1450122 Change-Id: I1267b099a5778041cbc8e91b7184844812145b93 Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com> Reviewed-on: http://git-master/r/422161 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c4
3 files changed, 24 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index f5d5e467..9492d646 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -406,17 +406,36 @@ static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add)
406 return gk20a_fifo_update_runlist(c->g, 0, c->hw_chid, add, true); 406 return gk20a_fifo_update_runlist(c->g, 0, c->hw_chid, add, true);
407} 407}
408 408
409void gk20a_disable_channel_no_update(struct channel_gk20a *ch) 409void gk20a_channel_abort(struct channel_gk20a *ch)
410{ 410{
411 struct channel_gk20a_job *job, *n;
412 bool released_job_semaphore = false;
413
411 /* ensure no fences are pending */ 414 /* ensure no fences are pending */
412 if (ch->sync) 415 if (ch->sync)
413 ch->sync->set_min_eq_max(ch->sync); 416 ch->sync->set_min_eq_max(ch->sync);
414 417
418 /* release all job semaphores (applies only to jobs that use
419 semaphore synchronization) */
420 mutex_lock(&ch->jobs_lock);
421 list_for_each_entry_safe(job, n, &ch->jobs, list) {
422 if (job->post_fence.semaphore) {
423 gk20a_semaphore_release(job->post_fence.semaphore);
424 released_job_semaphore = true;
425 }
426 }
427 mutex_unlock(&ch->jobs_lock);
428
415 /* disable channel */ 429 /* disable channel */
416 gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid), 430 gk20a_writel(ch->g, ccsr_channel_r(ch->hw_chid),
417 gk20a_readl(ch->g, 431 gk20a_readl(ch->g,
418 ccsr_channel_r(ch->hw_chid)) | 432 ccsr_channel_r(ch->hw_chid)) |
419 ccsr_channel_enable_clr_true_f()); 433 ccsr_channel_enable_clr_true_f());
434
435 if (released_job_semaphore) {
436 wake_up_interruptible_all(&ch->semaphore_wq);
437 gk20a_channel_update(ch, 0);
438 }
420} 439}
421 440
422int gk20a_wait_channel_idle(struct channel_gk20a *ch) 441int gk20a_wait_channel_idle(struct channel_gk20a *ch)
@@ -455,7 +474,7 @@ void gk20a_disable_channel(struct channel_gk20a *ch,
455 } 474 }
456 475
457 /* disable the channel from hw and increment syncpoints */ 476 /* disable the channel from hw and increment syncpoints */
458 gk20a_disable_channel_no_update(ch); 477 gk20a_channel_abort(ch);
459 478
460 gk20a_wait_channel_idle(ch); 479 gk20a_wait_channel_idle(ch);
461 480
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 84983cc6..60437e66 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -153,7 +153,7 @@ bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch,
153void gk20a_disable_channel(struct channel_gk20a *ch, 153void gk20a_disable_channel(struct channel_gk20a *ch,
154 bool wait_for_finish, 154 bool wait_for_finish,
155 unsigned long finish_timeout); 155 unsigned long finish_timeout);
156void gk20a_disable_channel_no_update(struct channel_gk20a *ch); 156void gk20a_channel_abort(struct channel_gk20a *ch);
157int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout); 157int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout);
158void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error); 158void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error);
159void gk20a_channel_semaphore_wakeup(struct gk20a *g); 159void gk20a_channel_semaphore_wakeup(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 2d09a840..f246c73e 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -1043,7 +1043,7 @@ static bool gk20a_fifo_handle_mmu_fault(struct gk20a *g)
1043 if (ch->in_use) { 1043 if (ch->in_use) {
1044 /* disable the channel from hw and increment 1044 /* disable the channel from hw and increment
1045 * syncpoints */ 1045 * syncpoints */
1046 gk20a_disable_channel_no_update(ch); 1046 gk20a_channel_abort(ch);
1047 1047
1048 /* remove the channel from runlist */ 1048 /* remove the channel from runlist */
1049 clear_bit(ch->hw_chid, 1049 clear_bit(ch->hw_chid,
@@ -1180,7 +1180,7 @@ void gk20a_fifo_recover_ch(struct gk20a *g, u32 hw_chid, bool verbose)
1180 struct channel_gk20a *ch = 1180 struct channel_gk20a *ch =
1181 g->fifo.channel + hw_chid; 1181 g->fifo.channel + hw_chid;
1182 1182
1183 gk20a_disable_channel_no_update(ch); 1183 gk20a_channel_abort(ch);
1184 for (i = 0; i < g->fifo.max_runlists; i++) 1184 for (i = 0; i < g->fifo.max_runlists; i++)
1185 gk20a_fifo_update_runlist(g, i, 1185 gk20a_fifo_update_runlist(g, i,
1186 hw_chid, false, false); 1186 hw_chid, false, false);