summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h2
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index e0beefb1..aeb115ef 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -985,12 +985,12 @@ unbind:
985 ch->vpr = false; 985 ch->vpr = false;
986 ch->vm = NULL; 986 ch->vm = NULL;
987 987
988 mutex_lock(&ch->submit_lock); 988 mutex_lock(&ch->last_submit.fence_lock);
989 gk20a_fence_put(ch->last_submit.pre_fence); 989 gk20a_fence_put(ch->last_submit.pre_fence);
990 gk20a_fence_put(ch->last_submit.post_fence); 990 gk20a_fence_put(ch->last_submit.post_fence);
991 ch->last_submit.pre_fence = NULL; 991 ch->last_submit.pre_fence = NULL;
992 ch->last_submit.post_fence = NULL; 992 ch->last_submit.post_fence = NULL;
993 mutex_unlock(&ch->submit_lock); 993 mutex_unlock(&ch->last_submit.fence_lock);
994 WARN_ON(ch->sync); 994 WARN_ON(ch->sync);
995 995
996 /* unlink all debug sessions */ 996 /* unlink all debug sessions */
@@ -1424,12 +1424,12 @@ int gk20a_alloc_channel_gpfifo(struct channel_gk20a *c,
1424 ch_vm = c->vm; 1424 ch_vm = c->vm;
1425 1425
1426 c->cmds_pending = false; 1426 c->cmds_pending = false;
1427 mutex_lock(&c->submit_lock); 1427 mutex_lock(&c->last_submit.fence_lock);
1428 gk20a_fence_put(c->last_submit.pre_fence); 1428 gk20a_fence_put(c->last_submit.pre_fence);
1429 gk20a_fence_put(c->last_submit.post_fence); 1429 gk20a_fence_put(c->last_submit.post_fence);
1430 c->last_submit.pre_fence = NULL; 1430 c->last_submit.pre_fence = NULL;
1431 c->last_submit.post_fence = NULL; 1431 c->last_submit.post_fence = NULL;
1432 mutex_unlock(&c->submit_lock); 1432 mutex_unlock(&c->last_submit.fence_lock);
1433 1433
1434 c->ramfc.offset = 0; 1434 c->ramfc.offset = 0;
1435 c->ramfc.size = ram_in_ramfc_s() / 8; 1435 c->ramfc.size = ram_in_ramfc_s() / 8;
@@ -1958,11 +1958,13 @@ static void gk20a_channel_clean_up_jobs(struct work_struct *work)
1958 */ 1958 */
1959 if (list_empty(&c->jobs)) { 1959 if (list_empty(&c->jobs)) {
1960 mutex_lock(&c->sync_lock); 1960 mutex_lock(&c->sync_lock);
1961 mutex_lock(&c->last_submit.fence_lock);
1961 if (c->sync && platform->aggressive_sync_destroy && 1962 if (c->sync && platform->aggressive_sync_destroy &&
1962 gk20a_fence_is_expired(c->last_submit.post_fence)) { 1963 gk20a_fence_is_expired(c->last_submit.post_fence)) {
1963 c->sync->destroy(c->sync); 1964 c->sync->destroy(c->sync);
1964 c->sync = NULL; 1965 c->sync = NULL;
1965 } 1966 }
1967 mutex_unlock(&c->last_submit.fence_lock);
1966 mutex_unlock(&c->sync_lock); 1968 mutex_unlock(&c->sync_lock);
1967 } 1969 }
1968 mutex_unlock(&c->jobs_lock); 1970 mutex_unlock(&c->jobs_lock);
@@ -2270,12 +2272,14 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
2270 incr_cmd->gp_put = c->gpfifo.put; 2272 incr_cmd->gp_put = c->gpfifo.put;
2271 } 2273 }
2272 2274
2275 mutex_lock(&c->last_submit.fence_lock);
2273 gk20a_fence_put(c->last_submit.pre_fence); 2276 gk20a_fence_put(c->last_submit.pre_fence);
2274 gk20a_fence_put(c->last_submit.post_fence); 2277 gk20a_fence_put(c->last_submit.post_fence);
2275 c->last_submit.pre_fence = pre_fence; 2278 c->last_submit.pre_fence = pre_fence;
2276 c->last_submit.post_fence = post_fence; 2279 c->last_submit.post_fence = post_fence;
2277 if (fence_out) 2280 if (fence_out)
2278 *fence_out = gk20a_fence_get(post_fence); 2281 *fence_out = gk20a_fence_get(post_fence);
2282 mutex_unlock(&c->last_submit.fence_lock);
2279 2283
2280 /* TODO! Check for errors... */ 2284 /* TODO! Check for errors... */
2281 gk20a_channel_add_job(c, pre_fence, post_fence, 2285 gk20a_channel_add_job(c, pre_fence, post_fence,
@@ -2325,6 +2329,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
2325 mutex_init(&c->ioctl_lock); 2329 mutex_init(&c->ioctl_lock);
2326 mutex_init(&c->jobs_lock); 2330 mutex_init(&c->jobs_lock);
2327 mutex_init(&c->submit_lock); 2331 mutex_init(&c->submit_lock);
2332 mutex_init(&c->last_submit.fence_lock);
2328 mutex_init(&c->timeout.lock); 2333 mutex_init(&c->timeout.lock);
2329 mutex_init(&c->sync_lock); 2334 mutex_init(&c->sync_lock);
2330 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler); 2335 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler);
@@ -2347,11 +2352,19 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
2347int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout) 2352int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout)
2348{ 2353{
2349 int err = 0; 2354 int err = 0;
2350 struct gk20a_fence *fence = ch->last_submit.post_fence; 2355 struct gk20a_fence *fence;
2351 2356
2352 if (!ch->cmds_pending) 2357 if (!ch->cmds_pending)
2353 return 0; 2358 return 0;
2354 2359
2360 mutex_lock(&ch->last_submit.fence_lock);
2361 fence = ch->last_submit.post_fence;
2362 if (!fence) {
2363 mutex_unlock(&ch->last_submit.fence_lock);
2364 return -EINVAL;
2365 }
2366 mutex_unlock(&ch->last_submit.fence_lock);
2367
2355 /* Do not wait for a timedout channel */ 2368 /* Do not wait for a timedout channel */
2356 if (ch->has_timedout) 2369 if (ch->has_timedout)
2357 return -ETIMEDOUT; 2370 return -ETIMEDOUT;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index d8951b94..74c920e4 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -152,9 +152,9 @@ struct channel_gk20a {
152 152
153 bool cmds_pending; 153 bool cmds_pending;
154 struct { 154 struct {
155 /* These fences should be accessed with submit_lock held. */
156 struct gk20a_fence *pre_fence; 155 struct gk20a_fence *pre_fence;
157 struct gk20a_fence *post_fence; 156 struct gk20a_fence *post_fence;
157 struct mutex fence_lock;
158 } last_submit; 158 } last_submit;
159 159
160 void (*remove_support)(struct channel_gk20a *); 160 void (*remove_support)(struct channel_gk20a *);