summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-10-21 16:14:09 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-10-22 14:41:24 -0400
commit75c09b96b409dfbd495081100e5fa82605651947 (patch)
tree3aab3b2e170926b0a3fe0e9e70b9bd8ed7caef3a /drivers
parent790173dcfd505d03bd5fb1a92e28bb53c94b0876 (diff)
gpu: nvgpu: Protect sync by an own lock
Protect creation and deletion of sync by an own mutex. This prevents deadlock in channel abort when abort is called from submit path. Bug 200147887 Change-Id: I5d6308b773c1d1a6a89d4590e2e74c74d691f79d Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/821127
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c14
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h1
2 files changed, 13 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 34b62ac4..c09586c5 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -312,10 +312,13 @@ void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a)
312 * resource at this point 312 * resource at this point
313 * if not, then it will be destroyed at channel_free() 313 * if not, then it will be destroyed at channel_free()
314 */ 314 */
315 mutex_lock(&ch_gk20a->sync_lock);
315 if (ch_gk20a->sync && ch_gk20a->sync->aggressive_destroy) { 316 if (ch_gk20a->sync && ch_gk20a->sync->aggressive_destroy) {
317
316 ch_gk20a->sync->destroy(ch_gk20a->sync); 318 ch_gk20a->sync->destroy(ch_gk20a->sync);
317 ch_gk20a->sync = NULL; 319 ch_gk20a->sync = NULL;
318 } 320 }
321 mutex_unlock(&ch_gk20a->sync_lock);
319} 322}
320 323
321int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch) 324int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch)
@@ -375,10 +378,10 @@ void gk20a_channel_abort(struct channel_gk20a *ch)
375 ch->g->ops.fifo.disable_channel(ch); 378 ch->g->ops.fifo.disable_channel(ch);
376 379
377 /* ensure no fences are pending */ 380 /* ensure no fences are pending */
378 mutex_lock(&ch->submit_lock); 381 mutex_lock(&ch->sync_lock);
379 if (ch->sync) 382 if (ch->sync)
380 ch->sync->set_min_eq_max(ch->sync); 383 ch->sync->set_min_eq_max(ch->sync);
381 mutex_unlock(&ch->submit_lock); 384 mutex_unlock(&ch->sync_lock);
382 385
383 /* release all job semaphores (applies only to jobs that use 386 /* release all job semaphores (applies only to jobs that use
384 semaphore synchronization) */ 387 semaphore synchronization) */
@@ -812,10 +815,12 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
812 channel_gk20a_free_priv_cmdbuf(ch); 815 channel_gk20a_free_priv_cmdbuf(ch);
813 816
814 /* sync must be destroyed before releasing channel vm */ 817 /* sync must be destroyed before releasing channel vm */
818 mutex_lock(&ch->sync_lock);
815 if (ch->sync) { 819 if (ch->sync) {
816 ch->sync->destroy(ch->sync); 820 ch->sync->destroy(ch->sync);
817 ch->sync = NULL; 821 ch->sync = NULL;
818 } 822 }
823 mutex_unlock(&ch->sync_lock);
819 824
820 /* release channel binding to the as_share */ 825 /* release channel binding to the as_share */
821 if (ch_vm->as_share) 826 if (ch_vm->as_share)
@@ -1772,11 +1777,13 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1772 * the sync resource 1777 * the sync resource
1773 */ 1778 */
1774 if (list_empty(&c->jobs)) { 1779 if (list_empty(&c->jobs)) {
1780 mutex_lock(&c->sync_lock);
1775 if (c->sync && c->sync->aggressive_destroy && 1781 if (c->sync && c->sync->aggressive_destroy &&
1776 gk20a_fence_is_expired(c->last_submit.post_fence)) { 1782 gk20a_fence_is_expired(c->last_submit.post_fence)) {
1777 c->sync->destroy(c->sync); 1783 c->sync->destroy(c->sync);
1778 c->sync = NULL; 1784 c->sync = NULL;
1779 } 1785 }
1786 mutex_unlock(&c->sync_lock);
1780 } 1787 }
1781 mutex_unlock(&c->jobs_lock); 1788 mutex_unlock(&c->jobs_lock);
1782 mutex_unlock(&c->submit_lock); 1789 mutex_unlock(&c->submit_lock);
@@ -1889,6 +1896,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1889 1896
1890 mutex_lock(&c->submit_lock); 1897 mutex_lock(&c->submit_lock);
1891 1898
1899 mutex_lock(&c->sync_lock);
1892 if (!c->sync) { 1900 if (!c->sync) {
1893 c->sync = gk20a_channel_sync_create(c); 1901 c->sync = gk20a_channel_sync_create(c);
1894 if (!c->sync) { 1902 if (!c->sync) {
@@ -1901,6 +1909,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
1901 if (err) 1909 if (err)
1902 return err; 1910 return err;
1903 } 1911 }
1912 mutex_unlock(&c->sync_lock);
1904 1913
1905 /* 1914 /*
1906 * optionally insert syncpt wait in the beginning of gpfifo submission 1915 * optionally insert syncpt wait in the beginning of gpfifo submission
@@ -2053,6 +2062,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
2053 mutex_init(&c->jobs_lock); 2062 mutex_init(&c->jobs_lock);
2054 mutex_init(&c->submit_lock); 2063 mutex_init(&c->submit_lock);
2055 mutex_init(&c->timeout.lock); 2064 mutex_init(&c->timeout.lock);
2065 mutex_init(&c->sync_lock);
2056 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler); 2066 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler);
2057 INIT_LIST_HEAD(&c->jobs); 2067 INIT_LIST_HEAD(&c->jobs);
2058#if defined(CONFIG_GK20A_CYCLE_STATS) 2068#if defined(CONFIG_GK20A_CYCLE_STATS)
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 3e18e053..794d8228 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -166,6 +166,7 @@ struct channel_gk20a {
166 struct nvgpu_notification *error_notifier; 166 struct nvgpu_notification *error_notifier;
167 void *error_notifier_va; 167 void *error_notifier_va;
168 168
169 struct mutex sync_lock;
169 struct gk20a_channel_sync *sync; 170 struct gk20a_channel_sync *sync;
170 171
171#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION 172#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION