mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
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>
This commit is contained in:
committed by
Dan Willemsen
parent
664ce15717
commit
ae22cda010
@@ -84,18 +84,16 @@ void gk20a_semaphore_pool_put(struct gk20a_semaphore_pool *p)
|
||||
}
|
||||
|
||||
static struct gk20a_semaphore_pool_map *
|
||||
gk20a_semaphore_pool_find_map(struct gk20a_semaphore_pool *p,
|
||||
struct vm_gk20a *vm)
|
||||
gk20a_semaphore_pool_find_map_locked(struct gk20a_semaphore_pool *p,
|
||||
struct vm_gk20a *vm)
|
||||
{
|
||||
struct gk20a_semaphore_pool_map *map, *found = NULL;
|
||||
mutex_lock(&p->maps_mutex);
|
||||
list_for_each_entry(map, &p->maps, list) {
|
||||
if (map->vm == vm) {
|
||||
found = map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&p->maps_mutex);
|
||||
return found;
|
||||
}
|
||||
|
||||
@@ -105,7 +103,6 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
|
||||
{
|
||||
struct gk20a_semaphore_pool_map *map;
|
||||
|
||||
WARN_ON(gk20a_semaphore_pool_find_map(p, vm));
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
return -ENOMEM;
|
||||
@@ -117,7 +114,10 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
|
||||
kfree(map);
|
||||
return -ENOMEM;
|
||||
}
|
||||
gk20a_vm_get(vm);
|
||||
|
||||
mutex_lock(&p->maps_mutex);
|
||||
WARN_ON(gk20a_semaphore_pool_find_map_locked(p, vm));
|
||||
list_add(&map->list, &p->maps);
|
||||
mutex_unlock(&p->maps_mutex);
|
||||
return 0;
|
||||
@@ -126,23 +126,33 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
|
||||
void gk20a_semaphore_pool_unmap(struct gk20a_semaphore_pool *p,
|
||||
struct vm_gk20a *vm)
|
||||
{
|
||||
struct gk20a_semaphore_pool_map *map =
|
||||
gk20a_semaphore_pool_find_map(p, vm);
|
||||
if (!map)
|
||||
return;
|
||||
gk20a_gmmu_unmap(vm, map->gpu_va, p->size, map->rw_flag);
|
||||
list_del(&map->list);
|
||||
kfree(map);
|
||||
struct gk20a_semaphore_pool_map *map;
|
||||
WARN_ON(!vm);
|
||||
|
||||
mutex_lock(&p->maps_mutex);
|
||||
map = gk20a_semaphore_pool_find_map_locked(p, vm);
|
||||
if (map) {
|
||||
gk20a_gmmu_unmap(vm, map->gpu_va, p->size, map->rw_flag);
|
||||
gk20a_vm_put(vm);
|
||||
list_del(&map->list);
|
||||
kfree(map);
|
||||
}
|
||||
mutex_unlock(&p->maps_mutex);
|
||||
}
|
||||
|
||||
u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *p,
|
||||
struct vm_gk20a *vm)
|
||||
{
|
||||
struct gk20a_semaphore_pool_map *map =
|
||||
gk20a_semaphore_pool_find_map(p, vm);
|
||||
if (!map)
|
||||
return 0;
|
||||
return map->gpu_va;
|
||||
struct gk20a_semaphore_pool_map *map;
|
||||
u64 gpu_va = 0;
|
||||
|
||||
mutex_lock(&p->maps_mutex);
|
||||
map = gk20a_semaphore_pool_find_map_locked(p, vm);
|
||||
if (map)
|
||||
gpu_va = map->gpu_va;
|
||||
mutex_unlock(&p->maps_mutex);
|
||||
|
||||
return gpu_va;
|
||||
}
|
||||
|
||||
struct gk20a_semaphore *gk20a_semaphore_alloc(struct gk20a_semaphore_pool *pool)
|
||||
|
||||
Reference in New Issue
Block a user