diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 14 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 |
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 | ||
321 | int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch) | 324 | int 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 |