From e323f562b2e391995c331af718ae49f672b8d2ed Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Wed, 27 Jun 2018 10:14:12 -0700 Subject: gpu: nvgpu: Keep lock while unreffing mappings In the vm_area free code, when unreffing the mappings owned by the vm_area, we need to continue holding the VM lock. Also add a comment specifying this requirement in the VM code. Bug 2156667 Change-Id: If0b430f045e4c585fcba2d3176163e5b19be8326 Signed-off-by: Alex Waterman Reviewed-on: https://git-master.nvidia.com/r/1763235 Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/mm/vm.c | 5 +++++ drivers/gpu/nvgpu/common/mm/vm_area.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index 13fd641e..3d9dd174 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -1094,6 +1094,11 @@ static void __nvgpu_vm_unmap(struct nvgpu_mapped_buf *mapped_buffer, nvgpu_kfree(g, mapped_buffer); } +/* + * Note: the update_gmmu_lock of the VM that owns this buffer must be locked + * before calling nvgpu_ref_put() with this function as the unref function + * argument since this can modify the tree of maps. + */ void __nvgpu_vm_unmap_ref(struct nvgpu_ref *ref) { struct nvgpu_mapped_buf *mapped_buffer = diff --git a/drivers/gpu/nvgpu/common/mm/vm_area.c b/drivers/gpu/nvgpu/common/mm/vm_area.c index 663d8999..5d3b0526 100644 --- a/drivers/gpu/nvgpu/common/mm/vm_area.c +++ b/drivers/gpu/nvgpu/common/mm/vm_area.c @@ -199,7 +199,6 @@ int nvgpu_vm_area_free(struct vm_gk20a *vm, u64 addr) return 0; } nvgpu_list_del(&vm_area->vm_area_list); - nvgpu_mutex_release(&vm->update_gmmu_lock); nvgpu_log(g, gpu_dbg_map, "DEL vm_area: pgsz=%#-8x pages=%-9llu " @@ -219,6 +218,8 @@ int nvgpu_vm_area_free(struct vm_gk20a *vm, u64 addr) nvgpu_ref_put(&buffer->ref, __nvgpu_vm_unmap_ref); } + nvgpu_mutex_release(&vm->update_gmmu_lock); + /* if this was a sparse mapping, free the va */ if (vm_area->sparse) g->ops.mm.gmmu_unmap(vm, -- cgit v1.2.2