mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
gpu:nvgpu: fix the nvs mmap issues
- As part of mmap call handler mmap_sem is being acquired which is causing an BUG: scheduling while atomic:. This is happening because mmap callback gets called with mmap_sem held. The mmap file handler is called via call_mmap() via mmap_region() via do_mmap(), and the caller of do_mmap() must hold down_write(¤t->mm->mmap_sem). To fix this issue removing the mmap_sem locking from nvs mmap handler. - If remap_vmalloc_range() is used to map the pages to userspace then allocated pages should be mapped into virtually contiguous space by passing VM_USERMAP flag to vmap(). Passing VM_USERMAP to vmap() call if API nvgpu_dma_alloc_flags_sys() is called with flag NVGPU_DMA_VM_USERMAP_ADDRESS. Bug 3884011 Change-Id: I64264f6f6e0dd75b1f828dc58355d740e6ef5ccb Signed-off-by: prsethi <prsethi@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2820781 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
0e6c8bb521
commit
b4494a4b86
@@ -260,6 +260,7 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
|
||||
gfp_t gfps = GFP_KERNEL|__GFP_ZERO;
|
||||
dma_addr_t iova;
|
||||
unsigned long dma_attrs = 0;
|
||||
unsigned long vma_flags = 0;
|
||||
void *alloc_ret;
|
||||
int err;
|
||||
|
||||
@@ -309,8 +310,18 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
|
||||
|
||||
/* Map the page list from the non-contiguous allocation */
|
||||
if (nvgpu_nvlink_non_contig(g, flags)) {
|
||||
/*
|
||||
* If remap_vmalloc_range() is going to be used to map cpu_va to
|
||||
* userspace then VM_USERMAP flag should be passed to vmap() to
|
||||
* get appropriate cpu_va.
|
||||
*/
|
||||
if (flags & NVGPU_DMA_VM_USERMAP_ADDRESS) {
|
||||
vma_flags |= VM_USERMAP;
|
||||
}
|
||||
|
||||
mem->cpu_va = vmap(mem->priv.pages, size >> PAGE_SHIFT,
|
||||
0, PAGE_KERNEL);
|
||||
vma_flags, PAGE_KERNEL);
|
||||
|
||||
if (!mem->cpu_va) {
|
||||
err = -ENOMEM;
|
||||
goto fail_free_sgt;
|
||||
@@ -365,12 +376,6 @@ int nvgpu_dma_mmap_sys(struct gk20a *g, struct vm_area_struct *vma, struct nvgpu
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
mmap_write_lock(vma->vm_mm);
|
||||
#else
|
||||
down_write(&vma->vm_mm->mmap_sem);
|
||||
#endif
|
||||
|
||||
vma_exists = find_vma_intersection(vma->vm_mm, vma->vm_start, vma->vm_end);
|
||||
if (vma_exists != NULL) {
|
||||
err = -EEXIST;
|
||||
@@ -395,14 +400,9 @@ int nvgpu_dma_mmap_sys(struct gk20a *g, struct vm_area_struct *vma, struct nvgpu
|
||||
}
|
||||
|
||||
done:
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
mmap_write_unlock(vma->vm_mm);
|
||||
#else
|
||||
up_write(&vma->vm_mm->mmap_sem);
|
||||
#endif
|
||||
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "failed to map mem into userspace vma");
|
||||
nvgpu_err(g, "failed to map mem into userspace vma %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user