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>
This commit is contained in:
Lauri Peltonen
2014-04-07 19:21:44 +03:00
committed by Dan Willemsen
parent 9727cf87bc
commit 9c5d336fb7

View File

@@ -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);
/* 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. */
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. */
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;