diff options
author | Alex Waterman <alexw@nvidia.com> | 2017-05-09 19:41:18 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-06-06 20:09:11 -0400 |
commit | c2b63150cd947557b8d17637258b988459b8e0ec (patch) | |
tree | 5b15911b0b4799538ca98c9b6c1a31c0cbfe4a99 /drivers/gpu/nvgpu/common | |
parent | 6bd7d22c0f248d0d29ea44b06798b247d0d2753a (diff) |
gpu: nvgpu: Unify vm_init for vGPU and regular GPU
Unify the initialization routines for the vGPU and regular GPU paths.
This helps avoid any further code divergence. This also assumes that
the code running on the regular GPU essentially works for the vGPU.
The only addition is that the regular GPU path calls an API in the
vGPU code that sends the necessary RM server message.
JIRA NVGPU-12
JIRA NVGPU-30
Change-Id: I37af1993fd8b50f666ae27524d382cce49cf28f7
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/1480226
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/as.c | 63 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/mm/vm.c | 27 |
2 files changed, 85 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/common/as.c b/drivers/gpu/nvgpu/common/as.c index 3182642a..481fb807 100644 --- a/drivers/gpu/nvgpu/common/as.c +++ b/drivers/gpu/nvgpu/common/as.c | |||
@@ -16,8 +16,10 @@ | |||
16 | #include <trace/events/gk20a.h> | 16 | #include <trace/events/gk20a.h> |
17 | 17 | ||
18 | #include <nvgpu/kmem.h> | 18 | #include <nvgpu/kmem.h> |
19 | #include <nvgpu/vm.h> | ||
19 | 20 | ||
20 | #include "gk20a/gk20a.h" | 21 | #include "gk20a/gk20a.h" |
22 | #include "gk20a/platform_gk20a.h" | ||
21 | 23 | ||
22 | /* dumb allocator... */ | 24 | /* dumb allocator... */ |
23 | static int generate_as_share_id(struct gk20a_as *as) | 25 | static int generate_as_share_id(struct gk20a_as *as) |
@@ -32,6 +34,51 @@ static void release_as_share_id(struct gk20a_as *as, int id) | |||
32 | return; | 34 | return; |
33 | } | 35 | } |
34 | 36 | ||
37 | /* address space interfaces for the gk20a module */ | ||
38 | static int gk20a_vm_alloc_share(struct gk20a_as_share *as_share, | ||
39 | u32 big_page_size, u32 flags) | ||
40 | { | ||
41 | struct gk20a_as *as = as_share->as; | ||
42 | struct gk20a *g = gk20a_from_as(as); | ||
43 | struct mm_gk20a *mm = &g->mm; | ||
44 | struct vm_gk20a *vm; | ||
45 | char name[32]; | ||
46 | int err; | ||
47 | const bool userspace_managed = | ||
48 | (flags & NVGPU_GPU_IOCTL_ALLOC_AS_FLAGS_USERSPACE_MANAGED) != 0; | ||
49 | |||
50 | gk20a_dbg_fn(""); | ||
51 | |||
52 | if (big_page_size == 0) { | ||
53 | big_page_size = | ||
54 | gk20a_get_platform(g->dev)->default_big_page_size; | ||
55 | } else { | ||
56 | if (!is_power_of_2(big_page_size)) | ||
57 | return -EINVAL; | ||
58 | |||
59 | if (!(big_page_size & g->gpu_characteristics.available_big_page_sizes)) | ||
60 | return -EINVAL; | ||
61 | } | ||
62 | |||
63 | vm = nvgpu_kzalloc(g, sizeof(*vm)); | ||
64 | if (!vm) | ||
65 | return -ENOMEM; | ||
66 | |||
67 | as_share->vm = vm; | ||
68 | vm->as_share = as_share; | ||
69 | vm->enable_ctag = true; | ||
70 | |||
71 | snprintf(name, sizeof(name), "as_%d", as_share->id); | ||
72 | |||
73 | err = nvgpu_init_vm(mm, vm, big_page_size, | ||
74 | big_page_size << 10, | ||
75 | mm->channel.kernel_size, | ||
76 | mm->channel.user_size + mm->channel.kernel_size, | ||
77 | !mm->disable_bigpage, userspace_managed, name); | ||
78 | |||
79 | return err; | ||
80 | } | ||
81 | |||
35 | int gk20a_as_alloc_share(struct gk20a *g, | 82 | int gk20a_as_alloc_share(struct gk20a *g, |
36 | u32 big_page_size, u32 flags, | 83 | u32 big_page_size, u32 flags, |
37 | struct gk20a_as_share **out) | 84 | struct gk20a_as_share **out) |
@@ -56,7 +103,7 @@ int gk20a_as_alloc_share(struct gk20a *g, | |||
56 | err = gk20a_busy(g); | 103 | err = gk20a_busy(g); |
57 | if (err) | 104 | if (err) |
58 | goto failed; | 105 | goto failed; |
59 | err = g->ops.mm.vm_alloc_share(as_share, big_page_size, flags); | 106 | err = gk20a_vm_alloc_share(as_share, big_page_size, flags); |
60 | gk20a_idle(g); | 107 | gk20a_idle(g); |
61 | 108 | ||
62 | if (err) | 109 | if (err) |
@@ -70,6 +117,20 @@ failed: | |||
70 | return err; | 117 | return err; |
71 | } | 118 | } |
72 | 119 | ||
120 | int gk20a_vm_release_share(struct gk20a_as_share *as_share) | ||
121 | { | ||
122 | struct vm_gk20a *vm = as_share->vm; | ||
123 | |||
124 | gk20a_dbg_fn(""); | ||
125 | |||
126 | vm->as_share = NULL; | ||
127 | as_share->vm = NULL; | ||
128 | |||
129 | nvgpu_vm_put(vm); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
73 | /* | 134 | /* |
74 | * channels and the device nodes call this to release. | 135 | * channels and the device nodes call this to release. |
75 | * once the ref_cnt hits zero the share is deleted. | 136 | * once the ref_cnt hits zero the share is deleted. |
diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index b957e755..171a67ca 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <nvgpu/semaphore.h> | 24 | #include <nvgpu/semaphore.h> |
25 | #include <nvgpu/enabled.h> | 25 | #include <nvgpu/enabled.h> |
26 | 26 | ||
27 | #include <nvgpu/vgpu/vm.h> | ||
28 | |||
27 | #include "gk20a/gk20a.h" | 29 | #include "gk20a/gk20a.h" |
28 | #include "gk20a/mm_gk20a.h" | 30 | #include "gk20a/mm_gk20a.h" |
29 | 31 | ||
@@ -209,10 +211,11 @@ static int nvgpu_init_sema_pool(struct vm_gk20a *vm) | |||
209 | * @vm - The VM to init. | 211 | * @vm - The VM to init. |
210 | * @big_page_size - Size of big pages associated with this VM. | 212 | * @big_page_size - Size of big pages associated with this VM. |
211 | * @low_hole - The size of the low hole (unaddressable memory at the bottom of | 213 | * @low_hole - The size of the low hole (unaddressable memory at the bottom of |
212 | * the address space. | 214 | * the address space). |
213 | * @kernel_reserved - Space reserved for kernel only allocations. | 215 | * @kernel_reserved - Space reserved for kernel only allocations. |
214 | * @aperture_size - Total size of the aperture. | 216 | * @aperture_size - Total size of the aperture. |
215 | * @big_pages - Ignored. Will be set based on other passed params. | 217 | * @big_pages - If true then big pages are possible in the VM. Note this does |
218 | * not guarantee that big pages will be possible. | ||
216 | * @name - Name of the address space. | 219 | * @name - Name of the address space. |
217 | * | 220 | * |
218 | * This function initializes an address space according to the following map: | 221 | * This function initializes an address space according to the following map: |
@@ -284,10 +287,21 @@ int nvgpu_init_vm(struct mm_gk20a *mm, | |||
284 | vm->userspace_managed = userspace_managed; | 287 | vm->userspace_managed = userspace_managed; |
285 | vm->mmu_levels = g->ops.mm.get_mmu_levels(g, vm->big_page_size); | 288 | vm->mmu_levels = g->ops.mm.get_mmu_levels(g, vm->big_page_size); |
286 | 289 | ||
290 | #ifdef CONFIG_TEGRA_GR_VIRTUALIZATION | ||
291 | if (g->is_virtual && userspace_managed) { | ||
292 | nvgpu_err(g, "vGPU: no userspace managed addr space support"); | ||
293 | return -ENOSYS; | ||
294 | } | ||
295 | if (g->is_virtual && vgpu_vm_init(g, vm)) { | ||
296 | nvgpu_err(g, "Failed to init vGPU VM!"); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | #endif | ||
300 | |||
287 | /* Initialize the page table data structures. */ | 301 | /* Initialize the page table data structures. */ |
288 | err = nvgpu_vm_init_page_tables(vm); | 302 | err = nvgpu_vm_init_page_tables(vm); |
289 | if (err) | 303 | if (err) |
290 | return err; | 304 | goto clean_up_vgpu_vm; |
291 | 305 | ||
292 | /* Setup vma limits. */ | 306 | /* Setup vma limits. */ |
293 | if (kernel_reserved + low_hole < aperture_size) { | 307 | if (kernel_reserved + low_hole < aperture_size) { |
@@ -445,6 +459,11 @@ clean_up_page_tables: | |||
445 | /* Cleans up nvgpu_vm_init_page_tables() */ | 459 | /* Cleans up nvgpu_vm_init_page_tables() */ |
446 | nvgpu_vfree(g, vm->pdb.entries); | 460 | nvgpu_vfree(g, vm->pdb.entries); |
447 | free_gmmu_pages(vm, &vm->pdb); | 461 | free_gmmu_pages(vm, &vm->pdb); |
462 | clean_up_vgpu_vm: | ||
463 | #ifdef CONFIG_TEGRA_GR_VIRTUALIZATION | ||
464 | if (g->is_virtual) | ||
465 | vgpu_vm_remove(vm); | ||
466 | #endif | ||
448 | return err; | 467 | return err; |
449 | } | 468 | } |
450 | 469 | ||
@@ -503,7 +522,7 @@ void __nvgpu_vm_remove(struct vm_gk20a *vm) | |||
503 | 522 | ||
504 | #ifdef CONFIG_TEGRA_GR_VIRTUALIZATION | 523 | #ifdef CONFIG_TEGRA_GR_VIRTUALIZATION |
505 | if (g->is_virtual) | 524 | if (g->is_virtual) |
506 | nvgpu_vm_remove_vgpu(vm); | 525 | vgpu_vm_remove(vm); |
507 | #endif | 526 | #endif |
508 | 527 | ||
509 | nvgpu_mutex_release(&vm->update_gmmu_lock); | 528 | nvgpu_mutex_release(&vm->update_gmmu_lock); |