summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorKirill Artamonov <kartamonov@nvidia.com>2014-05-17 01:09:07 +0300
committerRiham Haidar <rhaidar@nvidia.com>2014-05-21 11:19:32 -0700
commit8b6c5bb19dc4c169fb898cf5b2dc6022cffecf85 (patch)
tree54bd631a37b5b2f83d55026009ff69d8bdc89e27 /drivers/gpu
parent3e53778a572f06ce86d23bbd0fb338162d3b51d9 (diff)
gpu: nvgpu: fix pte memory leak
Force cleanup of all GMMU PTEs when releasing vm. bug 1514178 Signed-off-by: Kirill Artamonov <kartamonov@nvidia.com> Change-Id: Ice1ff837ca4decbdec2d4a78ea5eb64bfeefc0db Reviewed-on: http://git-master/r/411198 (cherry picked from commit e14ee5646554fd6cd812f4e7edf220c40116d722) Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/411895 Reviewed-by: Thomas Cherry <tcherry@nvidia.com> Tested-by: Ishwarya Balaji Gururajan <igururajan@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 1d6cdb53c05b..9de589f9d6e2 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -2013,6 +2013,7 @@ static void gk20a_vm_remove_support(struct vm_gk20a *vm)
struct mapped_buffer_node *mapped_buffer;
struct vm_reserved_va_node *va_node, *va_node_tmp;
struct rb_node *node;
+ int i;
gk20a_dbg_fn("");
mutex_lock(&vm->update_gmmu_lock);
@@ -2035,8 +2036,25 @@ static void gk20a_vm_remove_support(struct vm_gk20a *vm)
kfree(va_node);
}
- /* TBD: unmapping all buffers above may not actually free
+ /* unmapping all buffers above may not actually free
* all vm ptes. jettison them here for certain... */
+ for (i = 0; i < vm->pdes.num_pdes; i++) {
+ struct page_table_gk20a *pte =
+ &vm->pdes.ptes[gmmu_page_size_small][i];
+ if (pte->ref) {
+ free_gmmu_pages(vm, pte->ref, pte->sgt,
+ vm->mm->page_table_sizing[gmmu_page_size_small].order,
+ pte->size);
+ pte->ref = NULL;
+ }
+ pte = &vm->pdes.ptes[gmmu_page_size_big][i];
+ if (pte->ref) {
+ free_gmmu_pages(vm, pte->ref, pte->sgt,
+ vm->mm->page_table_sizing[gmmu_page_size_big].order,
+ pte->size);
+ pte->ref = NULL;
+ }
+ }
unmap_gmmu_pages(vm->pdes.ref, vm->pdes.sgt, vm->pdes.kv);
free_gmmu_pages(vm, vm->pdes.ref, vm->pdes.sgt, 0, vm->pdes.size);