mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +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 *
|
static struct gk20a_semaphore_pool_map *
|
||||||
gk20a_semaphore_pool_find_map(struct gk20a_semaphore_pool *p,
|
gk20a_semaphore_pool_find_map_locked(struct gk20a_semaphore_pool *p,
|
||||||
struct vm_gk20a *vm)
|
struct vm_gk20a *vm)
|
||||||
{
|
{
|
||||||
struct gk20a_semaphore_pool_map *map, *found = NULL;
|
struct gk20a_semaphore_pool_map *map, *found = NULL;
|
||||||
mutex_lock(&p->maps_mutex);
|
|
||||||
list_for_each_entry(map, &p->maps, list) {
|
list_for_each_entry(map, &p->maps, list) {
|
||||||
if (map->vm == vm) {
|
if (map->vm == vm) {
|
||||||
found = map;
|
found = map;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&p->maps_mutex);
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +103,6 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
|
|||||||
{
|
{
|
||||||
struct gk20a_semaphore_pool_map *map;
|
struct gk20a_semaphore_pool_map *map;
|
||||||
|
|
||||||
WARN_ON(gk20a_semaphore_pool_find_map(p, vm));
|
|
||||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||||
if (!map)
|
if (!map)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -117,7 +114,10 @@ int gk20a_semaphore_pool_map(struct gk20a_semaphore_pool *p,
|
|||||||
kfree(map);
|
kfree(map);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
gk20a_vm_get(vm);
|
||||||
|
|
||||||
mutex_lock(&p->maps_mutex);
|
mutex_lock(&p->maps_mutex);
|
||||||
|
WARN_ON(gk20a_semaphore_pool_find_map_locked(p, vm));
|
||||||
list_add(&map->list, &p->maps);
|
list_add(&map->list, &p->maps);
|
||||||
mutex_unlock(&p->maps_mutex);
|
mutex_unlock(&p->maps_mutex);
|
||||||
return 0;
|
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,
|
void gk20a_semaphore_pool_unmap(struct gk20a_semaphore_pool *p,
|
||||||
struct vm_gk20a *vm)
|
struct vm_gk20a *vm)
|
||||||
{
|
{
|
||||||
struct gk20a_semaphore_pool_map *map =
|
struct gk20a_semaphore_pool_map *map;
|
||||||
gk20a_semaphore_pool_find_map(p, vm);
|
WARN_ON(!vm);
|
||||||
if (!map)
|
|
||||||
return;
|
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_gmmu_unmap(vm, map->gpu_va, p->size, map->rw_flag);
|
||||||
|
gk20a_vm_put(vm);
|
||||||
list_del(&map->list);
|
list_del(&map->list);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&p->maps_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *p,
|
u64 gk20a_semaphore_pool_gpu_va(struct gk20a_semaphore_pool *p,
|
||||||
struct vm_gk20a *vm)
|
struct vm_gk20a *vm)
|
||||||
{
|
{
|
||||||
struct gk20a_semaphore_pool_map *map =
|
struct gk20a_semaphore_pool_map *map;
|
||||||
gk20a_semaphore_pool_find_map(p, vm);
|
u64 gpu_va = 0;
|
||||||
if (!map)
|
|
||||||
return 0;
|
mutex_lock(&p->maps_mutex);
|
||||||
return map->gpu_va;
|
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)
|
struct gk20a_semaphore *gk20a_semaphore_alloc(struct gk20a_semaphore_pool *pool)
|
||||||
|
|||||||
Reference in New Issue
Block a user