summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2017-08-29 15:59:40 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-09-12 18:54:46 -0400
commit72f40c211eca854f713530e68f789d4a7c3bb9fa (patch)
tree5378f6b8103c1ea902077ecfa2a56f6a353589fd /drivers/gpu
parentb79c165fd74f8269000f33691d8a480359e71585 (diff)
gpu: nvgpu: page align DMA allocs
Explicitly page align DMA memory allocations. Non-page aligned DMA allocs can lead to nvgpu_mem structs that have a size that's not page aligned. Those allocs, in some cases, can cause vGPU maps to return an error. More generally DMA allocs in Linux are never going to not be page aligned both in size and address. So might as well page align the alloc size to make code else where in the driver more simple. To imlpement this an aligned_size field has been added to struct nvgpu_mem. This field has the real page aligned size of the allocation. The original size is still saved in size. Change-Id: Ie08cfc4f39d5f97db84a54b8e314ad1fa53b72be Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1547902 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/common/linux/dma.c27
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h1
3 files changed, 22 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c
index cd6ad1b2..13c1c347 100644
--- a/drivers/gpu/nvgpu/common/linux/dma.c
+++ b/drivers/gpu/nvgpu/common/linux/dma.c
@@ -112,6 +112,13 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
112 112
113 gk20a_dbg_fn(""); 113 gk20a_dbg_fn("");
114 114
115 /*
116 * Save the old size but for actual allocation purposes the size is
117 * going to be page aligned.
118 */
119 mem->size = size;
120 size = PAGE_ALIGN(size);
121
115 if (flags) { 122 if (flags) {
116 DEFINE_DMA_ATTRS(dma_attrs); 123 DEFINE_DMA_ATTRS(dma_attrs);
117 124
@@ -148,7 +155,7 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
148 if (err) 155 if (err)
149 goto fail_free; 156 goto fail_free;
150 157
151 mem->size = size; 158 mem->aligned_size = size;
152 mem->aperture = APERTURE_SYSMEM; 159 mem->aperture = APERTURE_SYSMEM;
153 mem->priv.flags = flags; 160 mem->priv.flags = flags;
154 161
@@ -188,6 +195,9 @@ int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
188 195
189 gk20a_dbg_fn(""); 196 gk20a_dbg_fn("");
190 197
198 mem->size = size;
199 size = PAGE_ALIGN(size);
200
191 if (!nvgpu_alloc_initialized(&g->mm.vidmem.allocator)) 201 if (!nvgpu_alloc_initialized(&g->mm.vidmem.allocator))
192 return -ENOSYS; 202 return -ENOSYS;
193 203
@@ -228,7 +238,7 @@ int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
228 set_vidmem_page_alloc(mem->priv.sgt->sgl, addr); 238 set_vidmem_page_alloc(mem->priv.sgt->sgl, addr);
229 sg_set_page(mem->priv.sgt->sgl, NULL, size, 0); 239 sg_set_page(mem->priv.sgt->sgl, NULL, size, 0);
230 240
231 mem->size = size; 241 mem->aligned_size = size;
232 mem->aperture = APERTURE_VIDMEM; 242 mem->aperture = APERTURE_VIDMEM;
233 mem->allocator = vidmem_alloc; 243 mem->allocator = vidmem_alloc;
234 mem->priv.flags = flags; 244 mem->priv.flags = flags;
@@ -352,16 +362,16 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
352 nvgpu_dma_flags_to_attrs(&dma_attrs, mem->priv.flags); 362 nvgpu_dma_flags_to_attrs(&dma_attrs, mem->priv.flags);
353 363
354 if (mem->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) { 364 if (mem->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) {
355 dma_free_attrs(d, mem->size, mem->priv.pages, 365 dma_free_attrs(d, mem->aligned_size, mem->priv.pages,
356 sg_dma_address(mem->priv.sgt->sgl), 366 sg_dma_address(mem->priv.sgt->sgl),
357 __DMA_ATTR(dma_attrs)); 367 __DMA_ATTR(dma_attrs));
358 } else { 368 } else {
359 dma_free_attrs(d, mem->size, mem->cpu_va, 369 dma_free_attrs(d, mem->aligned_size, mem->cpu_va,
360 sg_dma_address(mem->priv.sgt->sgl), 370 sg_dma_address(mem->priv.sgt->sgl),
361 __DMA_ATTR(dma_attrs)); 371 __DMA_ATTR(dma_attrs));
362 } 372 }
363 } else { 373 } else {
364 dma_free_coherent(d, mem->size, mem->cpu_va, 374 dma_free_coherent(d, mem->aligned_size, mem->cpu_va,
365 sg_dma_address(mem->priv.sgt->sgl)); 375 sg_dma_address(mem->priv.sgt->sgl));
366 } 376 }
367 mem->cpu_va = NULL; 377 mem->cpu_va = NULL;
@@ -379,6 +389,7 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
379 nvgpu_free_sgtable(g, &mem->priv.sgt); 389 nvgpu_free_sgtable(g, &mem->priv.sgt);
380 390
381 mem->size = 0; 391 mem->size = 0;
392 mem->aligned_size = 0;
382 mem->aperture = APERTURE_INVALID; 393 mem->aperture = APERTURE_INVALID;
383} 394}
384 395
@@ -395,7 +406,8 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem)
395 was_empty = nvgpu_list_empty(&g->mm.vidmem.clear_list_head); 406 was_empty = nvgpu_list_empty(&g->mm.vidmem.clear_list_head);
396 nvgpu_list_add_tail(&mem->clear_list_entry, 407 nvgpu_list_add_tail(&mem->clear_list_entry,
397 &g->mm.vidmem.clear_list_head); 408 &g->mm.vidmem.clear_list_head);
398 atomic64_add(mem->size, &g->mm.vidmem.bytes_pending.atomic_var); 409 atomic64_add(mem->aligned_size,
410 &g->mm.vidmem.bytes_pending.atomic_var);
399 nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex); 411 nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex);
400 412
401 if (was_empty) { 413 if (was_empty) {
@@ -403,12 +415,13 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem)
403 schedule_work(&g->mm.vidmem.clear_mem_worker); 415 schedule_work(&g->mm.vidmem.clear_mem_worker);
404 } 416 }
405 } else { 417 } else {
406 nvgpu_memset(g, mem, 0, 0, mem->size); 418 nvgpu_memset(g, mem, 0, 0, mem->aligned_size);
407 nvgpu_free(mem->allocator, 419 nvgpu_free(mem->allocator,
408 (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); 420 (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl));
409 nvgpu_free_sgtable(g, &mem->priv.sgt); 421 nvgpu_free_sgtable(g, &mem->priv.sgt);
410 422
411 mem->size = 0; 423 mem->size = 0;
424 mem->aligned_size = 0;
412 mem->aperture = APERTURE_INVALID; 425 mem->aperture = APERTURE_INVALID;
413 } 426 }
414#endif 427#endif
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 2d69a2aa..a6507d2d 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -1207,7 +1207,7 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work)
1207 (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); 1207 (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl));
1208 nvgpu_free_sgtable(g, &mem->priv.sgt); 1208 nvgpu_free_sgtable(g, &mem->priv.sgt);
1209 1209
1210 WARN_ON(nvgpu_atomic64_sub_return(mem->size, 1210 WARN_ON(nvgpu_atomic64_sub_return(mem->aligned_size,
1211 &g->mm.vidmem.bytes_pending) < 0); 1211 &g->mm.vidmem.bytes_pending) < 0);
1212 mem->size = 0; 1212 mem->size = 0;
1213 mem->aperture = APERTURE_INVALID; 1213 mem->aperture = APERTURE_INVALID;
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h
index 5aa09f3d..f3be65c2 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h
@@ -50,6 +50,7 @@ struct nvgpu_mem {
50 */ 50 */
51 enum nvgpu_aperture aperture; 51 enum nvgpu_aperture aperture;
52 size_t size; 52 size_t size;
53 size_t aligned_size;
53 u64 gpu_va; 54 u64 gpu_va;
54 bool skip_wmb; 55 bool skip_wmb;
55 56