gpu: nvgpu: gk20a: add syncpt null checks

On channel_finish() path, we first check if last submit was
WFI and in that case we do not submit new WFI but just wait
on old syncpt fence.
But it is possible that sync resource is already freed from
another path (channel_suspend())
Hence add a NULL check there to prevent Null pointer
exception.
Also, in channel_free() path, move syncpt free API after
channel_unbind() since we logically free the syncpt after
unbinding the channel.

Bug 1305024

Change-Id: Icc2fc83f004310560fc459527e1d37730428ec2d
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/400233
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Shridhar Rasal <srasal@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2014-04-23 15:01:25 +05:30
committed by Dan Willemsen
parent eea79aaa60
commit b1538c3416

View File

@@ -659,11 +659,6 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
channel_gk20a_free_priv_cmdbuf(ch); channel_gk20a_free_priv_cmdbuf(ch);
if (ch->sync) {
ch->sync->destroy(ch->sync);
ch->sync = NULL;
}
/* release channel binding to the as_share */ /* release channel binding to the as_share */
gk20a_as_release_share(ch_vm->as_share); gk20a_as_release_share(ch_vm->as_share);
@@ -673,6 +668,11 @@ unbind:
ch->vpr = false; ch->vpr = false;
ch->vm = NULL; ch->vm = NULL;
if (ch->sync) {
ch->sync->destroy(ch->sync);
ch->sync = NULL;
}
WARN_ON(ch->sync); WARN_ON(ch->sync);
/* unlink all debug sessions */ /* unlink all debug sessions */
@@ -1697,12 +1697,15 @@ int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout)
gk20a_dbg_fn("waiting for channel to finish thresh:%d", gk20a_dbg_fn("waiting for channel to finish thresh:%d",
ch->last_submit_fence.thresh); ch->last_submit_fence.thresh);
err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence, timeout); if (ch->sync) {
if (WARN_ON(err)) err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence,
dev_warn(dev_from_gk20a(ch->g), timeout);
"timed out waiting for gk20a channel to finish"); if (WARN_ON(err))
else dev_warn(dev_from_gk20a(ch->g),
ch->cmds_pending = false; "timed out waiting for gk20a channel to finish");
else
ch->cmds_pending = false;
}
return err; return err;
} }
@@ -1903,8 +1906,9 @@ int gk20a_channel_suspend(struct gk20a *g)
return err; return err;
} }
c->sync->wait_cpu(c->sync, &c->last_submit_fence, if (c->sync)
500000); c->sync->wait_cpu(c->sync,
&c->last_submit_fence, 500000);
break; break;
} }
} }