From 0bb47c3675d2030545d40353931e2b8120541de4 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Fri, 5 May 2017 15:00:23 -0700 Subject: gpu: nvgpu: Add and use VM init/deinit APIs Remove the VM init/de-init from the HAL and instead use a single set of routines that init/de-init VMs. This prevents code divergence between vGPUs and regular GPUs. This patch also clears up the naming of the routines a little bit. Since some VMs are used inplace and others are dynamically allocated the APIs for freeing them were confusing. Also some free calls also clean up an instance block (this is API abuse - but this is how it currently exists). The new API looks like this: void __nvgpu_vm_remove(struct vm_gk20a *vm); void nvgpu_vm_remove(struct vm_gk20a *vm); void nvgpu_vm_remove_inst(struct vm_gk20a *vm, struct nvgpu_mem *inst_block); void nvgpu_vm_remove_vgpu(struct vm_gk20a *vm); int nvgpu_init_vm(struct mm_gk20a *mm, struct vm_gk20a *vm, u32 big_page_size, u64 low_hole, u64 kernel_reserved, u64 aperture_size, bool big_pages, bool userspace_managed, char *name); void nvgpu_deinit_vm(struct vm_gk20a *vm); JIRA NVGPU-12 JIRA NVGPU-30 Change-Id: Ia4016384c54746bfbcaa4bdd0d29d03d5d7f7f1b Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/1477747 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/common/mm/vm.c | 57 ++++++++++++++++++++++++--------- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 4 +-- drivers/gpu/nvgpu/gk20a/gk20a.h | 1 - drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 28 ++++------------ drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 4 +++ drivers/gpu/nvgpu/gm20b/mm_gm20b.c | 1 - drivers/gpu/nvgpu/gp10b/mm_gp10b.c | 2 +- drivers/gpu/nvgpu/include/nvgpu/vm.h | 25 ++++++++------- drivers/gpu/nvgpu/vgpu/mm_vgpu.c | 40 ++--------------------- 9 files changed, 72 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index e42c7c5a..bdc8554c 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -442,7 +442,22 @@ clean_up_page_tables: return err; } -void nvgpu_vm_remove_support_nofree(struct vm_gk20a *vm) +void nvgpu_deinit_vm(struct vm_gk20a *vm) +{ + if (nvgpu_alloc_initialized(&vm->kernel)) + nvgpu_alloc_destroy(&vm->kernel); + if (nvgpu_alloc_initialized(&vm->user)) + nvgpu_alloc_destroy(&vm->user); + if (nvgpu_alloc_initialized(&vm->user_lp)) + nvgpu_alloc_destroy(&vm->user_lp); + + gk20a_vm_free_entries(vm, &vm->pdb, 0); +} + +/* + * Cleanup the VM but don't nvgpu_kfree() on the vm pointer. + */ +void __nvgpu_vm_remove(struct vm_gk20a *vm) { struct nvgpu_mapped_buf *mapped_buffer; struct nvgpu_vm_area *vm_area, *vm_area_tmp; @@ -480,22 +495,40 @@ void nvgpu_vm_remove_support_nofree(struct vm_gk20a *vm) nvgpu_deinit_vm(vm); +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION + if (g->is_virtual) + nvgpu_vm_remove_vgpu(vm); +#endif + nvgpu_mutex_release(&vm->update_gmmu_lock); } -void nvgpu_vm_remove_support(struct vm_gk20a *vm) +/* + * Remove and nvgpu_kfree() the VM struct. + */ +void nvgpu_vm_remove(struct vm_gk20a *vm) { - nvgpu_vm_remove_support_nofree(vm); - /* vm is not used anymore. release it. */ + __nvgpu_vm_remove(vm); + nvgpu_kfree(vm->mm->g, vm); } -static void nvgpu_vm_remove_support_kref(struct kref *ref) +/* + * Note: this does not nvgpu_kfree() the vm. This might be a bug. + */ +void nvgpu_vm_remove_inst(struct vm_gk20a *vm, struct nvgpu_mem *inst_block) +{ + struct gk20a *g = vm->mm->g; + + gk20a_free_inst_block(g, inst_block); + __nvgpu_vm_remove(vm); +} + +static void __nvgpu_vm_remove_kref(struct kref *ref) { struct vm_gk20a *vm = container_of(ref, struct vm_gk20a, ref); - struct gk20a *g = gk20a_from_vm(vm); - g->ops.mm.vm_remove(vm); + nvgpu_vm_remove(vm); } void nvgpu_vm_get(struct vm_gk20a *vm) @@ -505,15 +538,7 @@ void nvgpu_vm_get(struct vm_gk20a *vm) void nvgpu_vm_put(struct vm_gk20a *vm) { - kref_put(&vm->ref, nvgpu_vm_remove_support_kref); -} - -void nvgpu_vm_remove(struct vm_gk20a *vm, struct nvgpu_mem *inst_block) -{ - struct gk20a *g = vm->mm->g; - - gk20a_free_inst_block(g, inst_block); - nvgpu_vm_remove_support_nofree(vm); + kref_put(&vm->ref, __nvgpu_vm_remove_kref); } int nvgpu_insert_mapped_buf(struct vm_gk20a *vm, diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 82bf7b3e..1f9b856d 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -1924,7 +1924,7 @@ static int gk20a_perfbuf_map(struct dbg_session_gk20a *dbg_s, err_unmap: nvgpu_vm_unmap_buffer(vm, args->offset, NULL); err_remove_vm: - nvgpu_vm_remove(vm, &mm->perfbuf.inst_block); + nvgpu_vm_remove_inst(vm, &mm->perfbuf.inst_block); nvgpu_mutex_release(&g->dbg_sessions_lock); return err; } @@ -1962,7 +1962,7 @@ static int gk20a_perfbuf_release_locked(struct gk20a *g, u64 offset) err = gk20a_perfbuf_disable_locked(g); nvgpu_vm_unmap_buffer(vm, offset, NULL); - nvgpu_vm_remove(vm, &mm->perfbuf.inst_block); + nvgpu_vm_remove_inst(vm, &mm->perfbuf.inst_block); g->perfbuf.owner = NULL; g->perfbuf.offset = 0; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index a8837433..ceadbae2 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -651,7 +651,6 @@ struct gpu_ops { int rw_flag, bool sparse, struct vm_gk20a_mapping_batch *batch); - void (*vm_remove)(struct vm_gk20a *vm); int (*vm_alloc_share)(struct gk20a_as_share *as_share, u32 big_page_size, u32 flags); int (*vm_bind_channel)(struct gk20a_as_share *as_share, diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 17f1622f..183a540a 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -464,7 +464,7 @@ static void gk20a_remove_mm_ce_support(struct mm_gk20a *mm) mm->vidmem.ce_ctx_id = (u32)~0; - nvgpu_vm_remove_support_nofree(&mm->ce.vm); + __nvgpu_vm_remove(&mm->ce.vm); } @@ -476,11 +476,11 @@ static void gk20a_remove_mm_support(struct mm_gk20a *mm) g->ops.mm.remove_bar2_vm(g); if (g->ops.mm.is_bar1_supported(g)) - nvgpu_vm_remove(&mm->bar1.vm, &mm->bar1.inst_block); + nvgpu_vm_remove_inst(&mm->bar1.vm, &mm->bar1.inst_block); - nvgpu_vm_remove(&mm->pmu.vm, &mm->pmu.inst_block); + nvgpu_vm_remove_inst(&mm->pmu.vm, &mm->pmu.inst_block); gk20a_free_inst_block(gk20a_from_mm(mm), &mm->hwpm.inst_block); - nvgpu_vm_remove_support_nofree(&mm->cde.vm); + __nvgpu_vm_remove(&mm->cde.vm); gk20a_semaphore_sea_destroy(g); gk20a_vidmem_destroy(g); @@ -2337,10 +2337,9 @@ void nvgpu_vm_unmap_locked(struct nvgpu_mapped_buf *mapped_buffer, return; } - -static void gk20a_vm_free_entries(struct vm_gk20a *vm, - struct gk20a_mm_entry *parent, - int level) +void gk20a_vm_free_entries(struct vm_gk20a *vm, + struct gk20a_mm_entry *parent, + int level) { int i; @@ -2663,18 +2662,6 @@ int nvgpu_vm_unmap_buffer(struct vm_gk20a *vm, u64 offset, return 0; } -void nvgpu_deinit_vm(struct vm_gk20a *vm) -{ - if (nvgpu_alloc_initialized(&vm->kernel)) - nvgpu_alloc_destroy(&vm->kernel); - if (nvgpu_alloc_initialized(&vm->user)) - nvgpu_alloc_destroy(&vm->user); - if (nvgpu_alloc_initialized(&vm->user_lp)) - nvgpu_alloc_destroy(&vm->user_lp); - - gk20a_vm_free_entries(vm, &vm->pdb, 0); -} - int gk20a_alloc_inst_block(struct gk20a *g, struct nvgpu_mem *inst_block) { int err; @@ -3151,7 +3138,6 @@ void gk20a_init_mm(struct gpu_ops *gops) { gops->mm.gmmu_map = gk20a_locked_gmmu_map; gops->mm.gmmu_unmap = gk20a_locked_gmmu_unmap; - gops->mm.vm_remove = nvgpu_vm_remove_support; gops->mm.vm_alloc_share = gk20a_vm_alloc_share; gops->mm.vm_bind_channel = gk20a_vm_bind_channel; gops->mm.fb_flush = gk20a_mm_fb_flush; diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 90a72811..4adf346e 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -463,4 +463,8 @@ int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, u64 *buffer_id, u64 *buffer_len); void gk20a_vm_unmap_locked_kref(struct kref *ref); +void gk20a_vm_free_entries(struct vm_gk20a *vm, + struct gk20a_mm_entry *parent, + int level); + #endif /* MM_GK20A_H */ diff --git a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c index 1405ef30..78e083d0 100644 --- a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c @@ -60,7 +60,6 @@ void gm20b_init_mm(struct gpu_ops *gops) gops->mm.support_sparse = gm20b_mm_support_sparse; gops->mm.gmmu_map = gk20a_locked_gmmu_map; gops->mm.gmmu_unmap = gk20a_locked_gmmu_unmap; - gops->mm.vm_remove = nvgpu_vm_remove_support; gops->mm.vm_alloc_share = gk20a_vm_alloc_share; gops->mm.vm_bind_channel = gk20a_vm_bind_channel; gops->mm.fb_flush = gk20a_mm_fb_flush; diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c index 6acea549..bc4aee3a 100644 --- a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c @@ -401,7 +401,7 @@ static void gp10b_remove_bar2_vm(struct gk20a *g) struct mm_gk20a *mm = &g->mm; gp10b_replayable_pagefault_buffer_deinit(g); - nvgpu_vm_remove(&mm->bar2.vm, &mm->bar2.inst_block); + nvgpu_vm_remove_inst(&mm->bar2.vm, &mm->bar2.inst_block); } diff --git a/drivers/gpu/nvgpu/include/nvgpu/vm.h b/drivers/gpu/nvgpu/include/nvgpu/vm.h index c89282bf..fed58f24 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vm.h @@ -225,19 +225,22 @@ int nvgpu_insert_mapped_buf(struct vm_gk20a *vm, void nvgpu_remove_mapped_buf(struct vm_gk20a *vm, struct nvgpu_mapped_buf *mapped_buffer); -void nvgpu_vm_remove_support_nofree(struct vm_gk20a *vm); -void nvgpu_vm_remove_support(struct vm_gk20a *vm); -void nvgpu_vm_remove(struct vm_gk20a *vm, struct nvgpu_mem *inst_block); +void __nvgpu_vm_remove(struct vm_gk20a *vm); +void nvgpu_vm_remove(struct vm_gk20a *vm); +void nvgpu_vm_remove_inst(struct vm_gk20a *vm, struct nvgpu_mem *inst_block); +#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION +void nvgpu_vm_remove_vgpu(struct vm_gk20a *vm); +#endif int nvgpu_init_vm(struct mm_gk20a *mm, - struct vm_gk20a *vm, - u32 big_page_size, - u64 low_hole, - u64 kernel_reserved, - u64 aperture_size, - bool big_pages, - bool userspace_managed, - char *name); + struct vm_gk20a *vm, + u32 big_page_size, + u64 low_hole, + u64 kernel_reserved, + u64 aperture_size, + bool big_pages, + bool userspace_managed, + char *name); void nvgpu_deinit_vm(struct vm_gk20a *vm); /* diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c index 63490aa5..db120d76 100644 --- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "vgpu/vgpu.h" @@ -200,52 +201,18 @@ static void vgpu_locked_gmmu_unmap(struct vm_gk20a *vm, /* TLB invalidate handled on server side */ } -static void vgpu_vm_remove_support(struct vm_gk20a *vm) +void nvgpu_vm_remove_vgpu(struct vm_gk20a *vm) { - struct gk20a *g = vm->mm->g; - struct nvgpu_mapped_buf *mapped_buffer; - struct nvgpu_vm_area *vm_area, *vm_area_tmp; + struct gk20a *g = gk20a_from_vm(vm); struct tegra_vgpu_cmd_msg msg; struct tegra_vgpu_as_share_params *p = &msg.params.as_share; - struct nvgpu_rbtree_node *node = NULL; int err; - gk20a_dbg_fn(""); - nvgpu_mutex_acquire(&vm->update_gmmu_lock); - - /* TBD: add a flag here for the unmap code to recognize teardown - * and short-circuit any otherwise expensive operations. */ - - nvgpu_rbtree_enum_start(0, &node, vm->mapped_buffers); - while (node) { - mapped_buffer = mapped_buffer_from_rbtree_node(node); - nvgpu_vm_unmap_locked(mapped_buffer, NULL); - nvgpu_rbtree_enum_start(0, &node, vm->mapped_buffers); - } - - /* destroy remaining reserved memory areas */ - nvgpu_list_for_each_entry_safe(vm_area, vm_area_tmp, - &vm->vm_area_list, - nvgpu_vm_area, vm_area_list) { - nvgpu_list_del(&vm_area->vm_area_list); - nvgpu_kfree(g, vm_area); - } - msg.cmd = TEGRA_VGPU_CMD_AS_FREE_SHARE; msg.handle = vgpu_get_handle(g); p->handle = vm->handle; err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); WARN_ON(err || msg.ret); - - if (nvgpu_alloc_initialized(&vm->kernel)) - nvgpu_alloc_destroy(&vm->kernel); - if (nvgpu_alloc_initialized(&vm->user)) - nvgpu_alloc_destroy(&vm->user); - - nvgpu_mutex_release(&vm->update_gmmu_lock); - - /* vm is not used anymore. release it. */ - nvgpu_kfree(g, vm); } u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt, u64 size) @@ -534,7 +501,6 @@ void vgpu_init_mm_ops(struct gpu_ops *gops) gops->fb.set_debug_mode = vgpu_mm_mmu_set_debug_mode; gops->mm.gmmu_map = vgpu_locked_gmmu_map; gops->mm.gmmu_unmap = vgpu_locked_gmmu_unmap; - gops->mm.vm_remove = vgpu_vm_remove_support; gops->mm.vm_alloc_share = vgpu_vm_alloc_share; gops->mm.vm_bind_channel = vgpu_vm_bind_channel; gops->mm.fb_flush = vgpu_mm_fb_flush; -- cgit v1.2.2