summaryrefslogtreecommitdiff
path: root/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
diff options
context:
space:
mode:
authorLauri Peltonen <lpeltonen@nvidia.com>2014-04-07 19:21:44 +0300
committerTerje Bergstrom <tbergstrom@nvidia.com>2014-04-09 05:09:46 -0700
commit0be1e6c1fb818fad44d552ef99006279dfd495c9 (patch)
tree376e38d7a48bbd2b58c28b74d175bcb7010cf224 /drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
parentf3fd7cec451d052b89fc567b04dd15a1940b9810 (diff)
gpu: nvgpu: Don't request host1x irq on channel wfi
Fix regression caused by commit 67fa249b419d32bfd0873fe5d924f4f01d9048de "video: tegra: host: Abstract gk20a channel synchronization". The above change unintentionally modified the channel synchronization logic so that an nvhost interrupt handler was scheduled also when idling the channel in gk20a_channel_submit_wfi. That appears to cause intermittent hangs when running CUDA tests. Bug 1484824 Change-Id: I4a1f85dd9e6215350f93710a2be9b0bbaef24b8f Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com> Reviewed-on: http://git-master/r/394127 Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index 851ae18b31bd..b94c0c930fd0 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -172,6 +172,7 @@ static void gk20a_channel_syncpt_update(void *priv, int nr_completed)
static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
bool gfx_class, bool wfi_cmd,
+ bool register_irq,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence)
{
@@ -184,18 +185,12 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
container_of(s, struct gk20a_channel_syncpt, ops);
struct channel_gk20a *c = sp->c;
- /* nvhost action_gpfifo_submit_complete releases this ref. */
- err = gk20a_channel_busy(c->g->dev);
- if (err)
- return err;
-
incr_cmd_size = 4;
if (wfi_cmd)
incr_cmd_size += 2;
gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd);
if (incr_cmd == NULL) {
- gk20a_channel_idle(c->g->dev);
gk20a_err(dev_from_gk20a(c->g),
"not enough priv cmd buffer space");
return -EAGAIN;
@@ -230,15 +225,22 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
thresh = nvhost_syncpt_incr_max_ext(sp->host1x_pdev, sp->id, 1);
- err = nvhost_intr_register_notifier(sp->host1x_pdev, sp->id, thresh,
- gk20a_channel_syncpt_update, c);
+ if (register_irq) {
+ /* nvhost action_gpfifo_submit_complete releases this ref. */
+ err = gk20a_channel_busy(c->g->dev);
+
+ if (!err) {
+ err = nvhost_intr_register_notifier(sp->host1x_pdev,
+ sp->id, thresh,
+ gk20a_channel_syncpt_update, c);
+ if (err)
+ gk20a_channel_idle(c->g->dev);
+ }
- /* Adding interrupt action should never fail. A proper error handling
- * here would require us to decrement the syncpt max back to its
- * original value. */
- if (WARN(err, "failed to set submit complete interrupt")) {
- gk20a_channel_idle(c->g->dev);
- err = 0; /* Ignore this error. */
+ /* Adding interrupt action should never fail. A proper error
+ * handling here would require us to decrement the syncpt max
+ * back to its original value. */
+ WARN(err, "failed to set submit complete interrupt");
}
fence->thresh = thresh;
@@ -255,6 +257,7 @@ int gk20a_channel_syncpt_incr_wfi(struct gk20a_channel_sync *s,
return __gk20a_channel_syncpt_incr(s,
false /* use host class */,
true /* wfi */,
+ false /* no irq handler */,
entry, fence);
}
@@ -269,6 +272,7 @@ int gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
return __gk20a_channel_syncpt_incr(s,
sp->c->obj_class == KEPLER_C /* may use gfx class */,
false /* no wfi */,
+ true /* register irq */,
entry, fence);
}
@@ -284,6 +288,7 @@ int gk20a_channel_syncpt_incr_user_syncpt(struct gk20a_channel_sync *s,
int err = __gk20a_channel_syncpt_incr(s,
sp->c->obj_class == KEPLER_C /* use gfx class? */,
sp->c->obj_class != KEPLER_C /* wfi if host class */,
+ true /* register irq */,
entry, fence);
if (err)
return err;