summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-04-23 05:31:25 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:09:43 -0400
commitb1538c34167c01cefb6308d7209978fa1e39b28e (patch)
treed7b4315176b556966151219a821f9ee9cb7ca6ad /drivers/gpu/nvgpu/gk20a
parenteea79aaa60087174adf7e6876ac089cb4734ebaf (diff)
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>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c30
1 files changed, 17 insertions, 13 deletions
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)
659 659
660 channel_gk20a_free_priv_cmdbuf(ch); 660 channel_gk20a_free_priv_cmdbuf(ch);
661 661
662 if (ch->sync) {
663 ch->sync->destroy(ch->sync);
664 ch->sync = NULL;
665 }
666
667 /* release channel binding to the as_share */ 662 /* release channel binding to the as_share */
668 gk20a_as_release_share(ch_vm->as_share); 663 gk20a_as_release_share(ch_vm->as_share);
669 664
@@ -673,6 +668,11 @@ unbind:
673 668
674 ch->vpr = false; 669 ch->vpr = false;
675 ch->vm = NULL; 670 ch->vm = NULL;
671
672 if (ch->sync) {
673 ch->sync->destroy(ch->sync);
674 ch->sync = NULL;
675 }
676 WARN_ON(ch->sync); 676 WARN_ON(ch->sync);
677 677
678 /* unlink all debug sessions */ 678 /* unlink all debug sessions */
@@ -1697,12 +1697,15 @@ int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout)
1697 gk20a_dbg_fn("waiting for channel to finish thresh:%d", 1697 gk20a_dbg_fn("waiting for channel to finish thresh:%d",
1698 ch->last_submit_fence.thresh); 1698 ch->last_submit_fence.thresh);
1699 1699
1700 err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence, timeout); 1700 if (ch->sync) {
1701 if (WARN_ON(err)) 1701 err = ch->sync->wait_cpu(ch->sync, &ch->last_submit_fence,
1702 dev_warn(dev_from_gk20a(ch->g), 1702 timeout);
1703 "timed out waiting for gk20a channel to finish"); 1703 if (WARN_ON(err))
1704 else 1704 dev_warn(dev_from_gk20a(ch->g),
1705 ch->cmds_pending = false; 1705 "timed out waiting for gk20a channel to finish");
1706 else
1707 ch->cmds_pending = false;
1708 }
1706 1709
1707 return err; 1710 return err;
1708} 1711}
@@ -1903,8 +1906,9 @@ int gk20a_channel_suspend(struct gk20a *g)
1903 return err; 1906 return err;
1904 } 1907 }
1905 1908
1906 c->sync->wait_cpu(c->sync, &c->last_submit_fence, 1909 if (c->sync)
1907 500000); 1910 c->sync->wait_cpu(c->sync,
1911 &c->last_submit_fence, 500000);
1908 break; 1912 break;
1909 } 1913 }
1910 } 1914 }