Skip to content

Commit 2b5b95b

Browse files
mm: introduce vma_set_file function v4
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. Signed-off-by: Christian König <[email protected]> Reviewed-by: Daniel Vetter <[email protected]> (v2) Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://patchwork.freedesktop.org/patch/394773/
1 parent 0227da0 commit 2b5b95b

File tree

10 files changed

+26
-19
lines changed

10 files changed

+26
-19
lines changed

drivers/dma-buf/dma-buf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,8 +1183,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
11831183
return -EINVAL;
11841184

11851185
/* readjust the vma */
1186-
fput(vma->vm_file);
1187-
vma->vm_file = get_file(dmabuf->file);
1186+
vma_set_file(vma, dmabuf->file);
11881187
vma->vm_pgoff = pgoff;
11891188

11901189
return dmabuf->ops->mmap(dmabuf, vma);

drivers/gpu/drm/etnaviv/etnaviv_gem.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,8 @@ static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
145145
* address_space (so unmap_mapping_range does what we want,
146146
* in particular in the case of mmap'd dmabufs)
147147
*/
148-
fput(vma->vm_file);
149-
get_file(etnaviv_obj->base.filp);
150148
vma->vm_pgoff = 0;
151-
vma->vm_file = etnaviv_obj->base.filp;
149+
vma_set_file(vma, etnaviv_obj->base.filp);
152150

153151
vma->vm_page_prot = vm_page_prot;
154152
}

drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
114114
if (ret)
115115
return ret;
116116

117-
fput(vma->vm_file);
118-
vma->vm_file = get_file(obj->base.filp);
117+
vma_set_file(vma, obj->base.filp);
119118

120119
return 0;
121120
}

drivers/gpu/drm/i915/gem/i915_gem_mman.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,8 +893,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
893893
* requires avoiding extraneous references to their filp, hence why
894894
* we prefer to use an anonymous file for their mmaps.
895895
*/
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);
898899

899900
switch (mmo->mmap_type) {
900901
case I915_MMAP_TYPE_WC:

drivers/gpu/drm/msm/msm_gem.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,8 @@ int msm_gem_mmap_obj(struct drm_gem_object *obj,
212212
* address_space (so unmap_mapping_range does what we want,
213213
* in particular in the case of mmap'd dmabufs)
214214
*/
215-
fput(vma->vm_file);
216-
get_file(obj->filp);
217215
vma->vm_pgoff = 0;
218-
vma->vm_file = obj->filp;
216+
vma_set_file(vma, obj->filp);
219217

220218
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
221219
}

drivers/gpu/drm/omapdrm/omap_gem.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,8 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj,
564564
* address_space (so unmap_mapping_range does what we want,
565565
* in particular in the case of mmap'd dmabufs)
566566
*/
567-
fput(vma->vm_file);
568567
vma->vm_pgoff = 0;
569-
vma->vm_file = get_file(obj->filp);
568+
vma_set_file(vma, obj->filp);
570569

571570
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
572571
}

drivers/gpu/drm/vgem/vgem_drv.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,7 @@ static int vgem_prime_mmap(struct drm_gem_object *obj,
397397
if (ret)
398398
return ret;
399399

400-
fput(vma->vm_file);
401-
vma->vm_file = get_file(obj->filp);
400+
vma_set_file(vma, obj->filp);
402401
vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
403402
vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
404403

drivers/staging/android/ashmem.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,9 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
450450
vma_set_anonymous(vma);
451451
}
452452

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);
456456

457457
out:
458458
mutex_unlock(&ashmem_mutex);

include/linux/mm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,8 @@ static inline void vma_set_page_prot(struct vm_area_struct *vma)
27192719
}
27202720
#endif
27212721

2722+
void vma_set_file(struct vm_area_struct *vma, struct file *file);
2723+
27222724
#ifdef CONFIG_NUMA_BALANCING
27232725
unsigned long change_prot_numa(struct vm_area_struct *vma,
27242726
unsigned long start, unsigned long end);

mm/mmap.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ void vma_set_page_prot(struct vm_area_struct *vma)
136136
WRITE_ONCE(vma->vm_page_prot, vm_page_prot);
137137
}
138138

139+
/*
140+
* Change backing file, only valid to use during initial VMA setup.
141+
*/
142+
void vma_set_file(struct vm_area_struct *vma, struct file *file)
143+
{
144+
/* Changing an anonymous vma with this is illegal */
145+
get_file(file);
146+
swap(vma->vm_file, file);
147+
fput(file);
148+
}
149+
EXPORT_SYMBOL(vma_set_file);
150+
139151
/*
140152
* Requires inode->i_mapping->i_mmap_rwsem
141153
*/

0 commit comments

Comments
 (0)