From b1538c34167c01cefb6308d7209978fa1e39b28e Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 23 Apr 2014 15:01:25 +0530 Subject: 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 Reviewed-on: http://git-master/r/400233 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Shridhar Rasal Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index d52e3f7e..344223ae 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -659,11 +659,6 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish) channel_gk20a_free_priv_cmdbuf(ch); - if (ch->sync) { - ch->sync->destroy(ch->sync); - ch->sync = NULL; - } - /* release channel binding to the as_share */ gk20a_as_release_share(ch_vm->as_share); @@ -673,6 +668,11 @@ unbind: ch->vpr = false; ch->vm = NULL; + + if (ch->sync) { + ch->sync->destroy(ch->sync); + ch->sync = NULL; + } WARN_ON(ch->sync); /* 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", ch->last_submit_fence.thresh); - err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence, timeout); - if (WARN_ON(err)) - dev_warn(dev_from_gk20a(ch->g), - "timed out waiting for gk20a channel to finish"); - else - ch->cmds_pending = false; + if (ch->sync) { + err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence, + timeout); + if (WARN_ON(err)) + dev_warn(dev_from_gk20a(ch->g), + "timed out waiting for gk20a channel to finish"); + else + ch->cmds_pending = false; + } return err; } @@ -1903,8 +1906,9 @@ int gk20a_channel_suspend(struct gk20a *g) return err; } - c->sync->wait_cpu(c->sync, &c->last_submit_fence, - 500000); + if (c->sync) + c->sync->wait_cpu(c->sync, + &c->last_submit_fence, 500000); break; } } -- cgit v1.2.2