summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2016-10-06 06:13:36 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-10-12 16:02:13 -0400
commitf5069622bb6233e62f8842c5136f2ea5e8c1e0c8 (patch)
tree00ff6bb17b442d7ddb480d05fcd694766bf365b8 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parent1b2529ba68bdd57231b59f2cb6d4f232e3956853 (diff)
gpu: nvgpu: make sure vidmem is cleared only once
Protect the initial vidmem zeroing performed during the first userspace alloc with a mutex, so that it blocks next concurrent users and is run only once. Otherwise, multiple clears could end up running in parallel, so that the next ones corrupt memory allocated by the thread that has finished earlier and advanced to allocate and use memory. Jira DNVGPU-84 Change-Id: If497749abf481b230835250191d011c4a9d1483b Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1232461 (cherry picked from commit 79435a68e6d2713b78acdb0ec6f77cfd78651d7f) Reviewed-on: http://git-master/r/1234990 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 570a3708..4c55f8ce 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -947,6 +947,8 @@ static int gk20a_init_vidmem(struct mm_gk20a *mm)
947 mm->vidmem.bootstrap_base = bootstrap_base; 947 mm->vidmem.bootstrap_base = bootstrap_base;
948 mm->vidmem.bootstrap_size = bootstrap_size; 948 mm->vidmem.bootstrap_size = bootstrap_size;
949 949
950 mutex_init(&mm->vidmem.first_clear_mutex);
951
950 INIT_WORK(&mm->vidmem.clear_mem_worker, gk20a_vidmem_clear_mem_worker); 952 INIT_WORK(&mm->vidmem.clear_mem_worker, gk20a_vidmem_clear_mem_worker);
951 atomic_set(&mm->vidmem.clears_pending, 0); 953 atomic_set(&mm->vidmem.clears_pending, 0);
952 INIT_LIST_HEAD(&mm->vidmem.clear_list_head); 954 INIT_LIST_HEAD(&mm->vidmem.clear_list_head);
@@ -2190,11 +2192,16 @@ int gk20a_vidmem_buf_alloc(struct gk20a *g, size_t bytes)
2190 buf->g = g; 2192 buf->g = g;
2191 2193
2192 if (!g->mm.vidmem.cleared) { 2194 if (!g->mm.vidmem.cleared) {
2193 err = gk20a_vidmem_clear_all(g); 2195 mutex_lock(&g->mm.vidmem.first_clear_mutex);
2194 if (err) { 2196 if (!g->mm.vidmem.cleared) {
2195 gk20a_err(g->dev, "failed to clear whole vidmem"); 2197 err = gk20a_vidmem_clear_all(g);
2196 goto err_kfree; 2198 if (err) {
2199 gk20a_err(g->dev,
2200 "failed to clear whole vidmem");
2201 goto err_kfree;
2202 }
2197 } 2203 }
2204 mutex_unlock(&g->mm.vidmem.first_clear_mutex);
2198 } 2205 }
2199 2206
2200 buf->mem = kzalloc(sizeof(struct mem_desc), GFP_KERNEL); 2207 buf->mem = kzalloc(sizeof(struct mem_desc), GFP_KERNEL);