Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: introduce vma_set_file function v5

Add the new vma_set_file() function to allow changing
vma->vm_file with the necessary refcount dance.

v2: add more users of this.
v3: add missing EXPORT_SYMBOL, rebase on mmap cleanup,
add comments why we drop the reference on two occasions.
v4: make it clear that changing an anonymous vma is illegal.
v5: move vma_set_file to mm/util.c

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Andrew Morton <akpm@linux-foundation.org>
Link: https://patchwork.freedesktop.org/patch/399360/

+26 -19
+1 -2
drivers/dma-buf/dma-buf.c
··· 1183 1183 return -EINVAL; 1184 1184 1185 1185 /* readjust the vma */ 1186 - fput(vma->vm_file); 1187 - vma->vm_file = get_file(dmabuf->file); 1186 + vma_set_file(vma, dmabuf->file); 1188 1187 vma->vm_pgoff = pgoff; 1189 1188 1190 1189 return dmabuf->ops->mmap(dmabuf, vma);
+1 -3
drivers/gpu/drm/etnaviv/etnaviv_gem.c
··· 145 145 * address_space (so unmap_mapping_range does what we want, 146 146 * in particular in the case of mmap'd dmabufs) 147 147 */ 148 - fput(vma->vm_file); 149 - get_file(etnaviv_obj->base.filp); 150 148 vma->vm_pgoff = 0; 151 - vma->vm_file = etnaviv_obj->base.filp; 149 + vma_set_file(vma, etnaviv_obj->base.filp); 152 150 153 151 vma->vm_page_prot = vm_page_prot; 154 152 }
+1 -2
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
··· 114 114 if (ret) 115 115 return ret; 116 116 117 - fput(vma->vm_file); 118 - vma->vm_file = get_file(obj->base.filp); 117 + vma_set_file(vma, obj->base.filp); 119 118 120 119 return 0; 121 120 }
+3 -2
drivers/gpu/drm/i915/gem/i915_gem_mman.c
··· 893 893 * requires avoiding extraneous references to their filp, hence why 894 894 * we prefer to use an anonymous file for their mmaps. 895 895 */ 896 - fput(vma->vm_file); 897 - vma->vm_file = anon; 896 + vma_set_file(vma, anon); 897 + /* Drop the initial creation reference, the vma is now holding one. */ 898 + fput(anon); 898 899 899 900 switch (mmo->mmap_type) { 900 901 case I915_MMAP_TYPE_WC:
+1 -3
drivers/gpu/drm/msm/msm_gem.c
··· 212 212 * address_space (so unmap_mapping_range does what we want, 213 213 * in particular in the case of mmap'd dmabufs) 214 214 */ 215 - fput(vma->vm_file); 216 - get_file(obj->filp); 217 215 vma->vm_pgoff = 0; 218 - vma->vm_file = obj->filp; 216 + vma_set_file(vma, obj->filp); 219 217 220 218 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 221 219 }
+1 -2
drivers/gpu/drm/omapdrm/omap_gem.c
··· 564 564 * address_space (so unmap_mapping_range does what we want, 565 565 * in particular in the case of mmap'd dmabufs) 566 566 */ 567 - fput(vma->vm_file); 568 567 vma->vm_pgoff = 0; 569 - vma->vm_file = get_file(obj->filp); 568 + vma_set_file(vma, obj->filp); 570 569 571 570 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 572 571 }
+1 -2
drivers/gpu/drm/vgem/vgem_drv.c
··· 403 403 if (ret) 404 404 return ret; 405 405 406 - fput(vma->vm_file); 407 - vma->vm_file = get_file(obj->filp); 406 + vma_set_file(vma, obj->filp); 408 407 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 409 408 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); 410 409
+3 -3
drivers/staging/android/ashmem.c
··· 450 450 vma_set_anonymous(vma); 451 451 } 452 452 453 - if (vma->vm_file) 454 - fput(vma->vm_file); 455 - vma->vm_file = asma->file; 453 + vma_set_file(vma, asma->file); 454 + /* XXX: merge this with the get_file() above if possible */ 455 + fput(asma->file); 456 456 457 457 out: 458 458 mutex_unlock(&ashmem_mutex);
+2
include/linux/mm.h
··· 2719 2719 } 2720 2720 #endif 2721 2721 2722 + void vma_set_file(struct vm_area_struct *vma, struct file *file); 2723 + 2722 2724 #ifdef CONFIG_NUMA_BALANCING 2723 2725 unsigned long change_prot_numa(struct vm_area_struct *vma, 2724 2726 unsigned long start, unsigned long end);
+12
mm/util.c
··· 311 311 return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); 312 312 } 313 313 314 + /* 315 + * Change backing file, only valid to use during initial VMA setup. 316 + */ 317 + void vma_set_file(struct vm_area_struct *vma, struct file *file) 318 + { 319 + /* Changing an anonymous vma with this is illegal */ 320 + get_file(file); 321 + swap(vma->vm_file, file); 322 + fput(file); 323 + } 324 + EXPORT_SYMBOL(vma_set_file); 325 + 314 326 #ifndef STACK_RND_MASK 315 327 #define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ 316 328 #endif