diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-04-01 05:14:46 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-04-19 11:15:37 -0400 |
commit | 1c96bc6942cdae7f4e90563687da7d068aea90bc (patch) | |
tree | 88e4923169670cbd9a8a50a03f8ca0ddba879e80 /drivers | |
parent | 2b2f84219c4bd21be9a7abf34334ec6d443c6c38 (diff) |
gpu: nvgpu: add lock for fences
All pre/post fence accesses in last_submit are
currently protected by submit lock
In order to remove the submit lock, move all fence
accesses under own lock i.e. fence_lock
Bug 200187553
Change-Id: I0132d1933dc92db8c5ed8c9311e49a030aa2d38c
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1120409
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 2 |
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) | |||
2347 | int gk20a_channel_finish(struct channel_gk20a *ch, unsigned long timeout) | 2352 | int 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 *); |