summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-02-25 18:13:19 -0500
committerAlexander Van Brunt <avanbrunt@nvidia.com>2015-05-05 16:55:44 -0400
commitd47b01d74f66ea1f1d68976dc4d602b4e299bd90 (patch)
treec0e2f9f5ae78cfc08741d85874f16386f5db1c32 /drivers
parent06be77da376f71ac9c73087ac02565cb6eec0eca (diff)
gpu: nvgpu: Free all page table levels
Convert the loop to free page tables into a recursive loop that goes through all levels. Change-Id: I3ab8f021bd8263f2f6dad29b5fbd0e6212c55a86 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/711393 Reviewed-on: http://git-master/r/737528 Reviewed-by: Alexander Van Brunt <avanbrunt@nvidia.com> Tested-by: Alexander Van Brunt <avanbrunt@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 43758712..45f6fd64 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -530,7 +530,9 @@ void free_gmmu_pages(struct vm_gk20a *vm,
530 DEFINE_DMA_ATTRS(attrs); 530 DEFINE_DMA_ATTRS(attrs);
531 531
532 gk20a_dbg_fn(""); 532 gk20a_dbg_fn("");
533 BUG_ON(entry->sgt == NULL); 533
534 if (!entry->sgt)
535 return;
534 536
535 if (tegra_platform_is_linsim()) { 537 if (tegra_platform_is_linsim()) {
536 free_gmmu_phys_pages(vm, entry); 538 free_gmmu_phys_pages(vm, entry);
@@ -554,6 +556,7 @@ void free_gmmu_pages(struct vm_gk20a *vm,
554 entry->pages = NULL; 556 entry->pages = NULL;
555 } 557 }
556 entry->size = 0; 558 entry->size = 0;
559 entry->sgt = NULL;
557} 560}
558 561
559int map_gmmu_pages(struct gk20a_mm_entry *entry) 562int map_gmmu_pages(struct gk20a_mm_entry *entry)
@@ -2140,13 +2143,28 @@ void gk20a_vm_unmap(struct vm_gk20a *vm, u64 offset)
2140 mutex_unlock(&vm->update_gmmu_lock); 2143 mutex_unlock(&vm->update_gmmu_lock);
2141} 2144}
2142 2145
2146static void gk20a_vm_free_entries(struct vm_gk20a *vm,
2147 struct gk20a_mm_entry *parent,
2148 int level)
2149{
2150 const struct gk20a_mmu_level *l = &vm->mmu_levels[level];
2151 int num_entries = 1 << (l->hi_bit[parent->pgsz] - l->lo_bit[parent->pgsz]);
2152 int i;
2153
2154 if (parent->entries)
2155 for (i = 0; i < num_entries; i++)
2156 gk20a_vm_free_entries(vm, &parent->entries[i], level+1);
2157
2158 if (parent->size)
2159 free_gmmu_pages(vm, parent);
2160 kfree(parent->entries);
2161}
2162
2143static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm) 2163static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm)
2144{ 2164{
2145 struct mapped_buffer_node *mapped_buffer; 2165 struct mapped_buffer_node *mapped_buffer;
2146 struct vm_reserved_va_node *va_node, *va_node_tmp; 2166 struct vm_reserved_va_node *va_node, *va_node_tmp;
2147 struct rb_node *node; 2167 struct rb_node *node;
2148 int i;
2149 u32 pde_lo = 0, pde_hi = 0;
2150 2168
2151 gk20a_dbg_fn(""); 2169 gk20a_dbg_fn("");
2152 mutex_lock(&vm->update_gmmu_lock); 2170 mutex_lock(&vm->update_gmmu_lock);
@@ -2169,17 +2187,6 @@ static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm)
2169 kfree(va_node); 2187 kfree(va_node);
2170 } 2188 }
2171 2189
2172 /* unmapping all buffers above may not actually free
2173 * all vm ptes. jettison them here for certain... */
2174 pde_range_from_vaddr_range(vm,
2175 0, vm->va_limit-1,
2176 &pde_lo, &pde_hi);
2177 for (i = 0; i < pde_hi + 1; i++) {
2178 struct gk20a_mm_entry *entry = &vm->pdb.entries[i];
2179 if (entry->size)
2180 free_gmmu_pages(vm, entry);
2181 }
2182
2183 gk20a_deinit_vm(vm); 2190 gk20a_deinit_vm(vm);
2184 2191
2185 mutex_unlock(&vm->update_gmmu_lock); 2192 mutex_unlock(&vm->update_gmmu_lock);
@@ -2709,9 +2716,7 @@ void gk20a_deinit_vm(struct vm_gk20a *vm)
2709 gk20a_allocator_destroy(&vm->vma[gmmu_page_size_big]); 2716 gk20a_allocator_destroy(&vm->vma[gmmu_page_size_big]);
2710 gk20a_allocator_destroy(&vm->vma[gmmu_page_size_small]); 2717 gk20a_allocator_destroy(&vm->vma[gmmu_page_size_small]);
2711 2718
2712 unmap_gmmu_pages(&vm->pdb); 2719 gk20a_vm_free_entries(vm, &vm->pdb, 0);
2713 free_gmmu_pages(vm, &vm->pdb);
2714 kfree(vm->pdb.entries);
2715} 2720}
2716 2721
2717int gk20a_alloc_inst_block(struct gk20a *g, struct mem_desc *inst_block) 2722int gk20a_alloc_inst_block(struct gk20a *g, struct mem_desc *inst_block)