summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c
diff options
context:
space:
mode:
authorLauri Peltonen <lpeltonen@nvidia.com>2014-06-11 07:06:27 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:10 -0400
commitae22cda010d26419476939fa46abf9345c412eff (patch)
tree1470e618ba100c05e7ce6d186a9bf1b4ce39f65c /drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c
parent664ce15717543b7909e8048e2cbc74be2a9ed6b9 (diff)
gpu: nvgpu: Improve locking in semaphore_gk20a.c
Fix some possible race conditions when manipulating the mapping list of semaphore pools. Acquire a reference to the vm in gk20a_semaphore_pool_map, and release that reference in gk20a_semaphore_pool_unmap. Bug 1450122 Change-Id: I204e9c3dffd5162538b93e628d016dc06b3a5fb6 Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com> Reviewed-on: http://git-master/r/422160 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c
index 55fa0e32..493c7b63 100644
--- a/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/semaphore_gk20a.c
@@ -84,18 +84,16 @@ void gk20a_semaphore_pool_put(struct gk20a_semaphore_pool *p)
84} 84}
85 85
86static struct gk20a_semaphore_pool_map * 86static struct gk20a_semaphore_pool_map *
87gk20a_semaphore_pool_find_map(struct gk20a_semaphore_pool *p, 87gk20a_semaphore_pool_find_map_locked(struct gk20a_semaphore_pool *p,
88 struct vm_gk20a *vm) 88 struct vm_gk20a *vm)
89{ 89{
90 struct gk20a_semaphore_pool_map *map, *found = NULL; 90 struct gk20a_semaphore_pool_map *map, *found = NULL;
91 mutex_lock(&p->maps_mutex);
92 list_for_each_entry(map, &p->maps, list) { 91 list_for_each_entry(map, &p->maps, list) {
93 if (map->vm == vm) { 92 if (map->vm == vm) {
94 found = map; 93 found = map;
95 break; 94 break;
96 } 95 }
97 } 96 }
98 mutex_unlock(&p->maps_mutex);
99 return found; 97 return found;
100} 98}
101 99
@@ -105,7 +103,6 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
105{ 103{
106 struct gk20a_semaphore_pool_map *map; 104 struct gk20a_semaphore_pool_map *map;
107 105
108 WARN_ON(gk20a_semaphore_pool_find_map(p, vm));
109 map = kzalloc(sizeof(*map), GFP_KERNEL); 106 map = kzalloc(sizeof(*map), GFP_KERNEL);
110 if (!map) 107 if (!map)
111 return -ENOMEM; 108 return -ENOMEM;
@@ -117,7 +114,10 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
117 kfree(map); 114 kfree(map);
118 return -ENOMEM; 115 return -ENOMEM;
119 } 116 }
117 gk20a_vm_get(vm);
118
120 mutex_lock(&p->maps_mutex); 119 mutex_lock(&p->maps_mutex);
120 WARN_ON(gk20a_semaphore_pool_find_map_locked(p, vm));
121 list_add(&map->list, &p->maps); 121 list_add(&map->list, &p->maps);
122 mutex_unlock(&p->maps_mutex); 122 mutex_unlock(&p->maps_mutex);
123 return 0; 123 return 0;
@@ -126,23 +126,33 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
126void gk20a_semaphore_pool_unmap(struct gk20a_semaphore_pool *p, 126void gk20a_semaphore_pool_unmap(struct gk20a_semaphore_pool *p,
127 struct vm_gk20a *vm) 127 struct vm_gk20a *vm)
128{ 128{
129 struct gk20a_semaphore_pool_map *map = 129 struct gk20a_semaphore_pool_map *map;
130 gk20a_semaphore_pool_find_map(p, vm); 130 WARN_ON(!vm);
131 if (!map) 131
132 return; 132 mutex_lock(&p->maps_mutex);
133 gk20a_gmmu_unmap(vm, map->gpu_va, p->size, map->rw_flag); 133 map = gk20a_semaphore_pool_find_map_locked(p, vm);
134 list_del(&map->list); 134 if (map) {
135 kfree(map); 135 gk20a_gmmu_unmap(vm, map->gpu_va, p->size, map->rw_flag);
136 gk20a_vm_put(vm);
137 list_del(&map->list);
138 kfree(map);
139 }
140 mutex_unlock(&p->maps_mutex);
136} 141}
137 142
138u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *p, 143u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *p,
139 struct vm_gk20a *vm) 144 struct vm_gk20a *vm)
140{ 145{
141 struct gk20a_semaphore_pool_map *map = 146 struct gk20a_semaphore_pool_map *map;
142 gk20a_semaphore_pool_find_map(p, vm); 147 u64 gpu_va = 0;
143 if (!map) 148
144 return 0; 149 mutex_lock(&p->maps_mutex);
145 return map->gpu_va; 150 map = gk20a_semaphore_pool_find_map_locked(p, vm);
151 if (map)
152 gpu_va = map->gpu_va;
153 mutex_unlock(&p->maps_mutex);
154
155 return gpu_va;
146} 156}
147 157
148struct gk20a_semaphore *gk20a_semaphore_alloc(struct gk20a_semaphore_pool *pool) 158struct gk20a_semaphore *gk20a_semaphore_alloc(struct gk20a_semaphore_pool *pool)