aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-07-21 16:48:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-07-21 16:48:51 -0400
commit3928d4f5ee37cdc523894f6e549e6aae521d8980 (patch)
treec328fd919e48fc8442db04d13c2ba1fe2c0f88e4
parent191a3afa98b857faf5231981ddbab66698034273 (diff)
mm: use helper functions for allocating and freeing vm_area structs
The vm_area_struct is one of the most fundamental memory management objects, but the management of it is entirely open-coded evertwhere, ranging from allocation and freeing (using kmem_cache_[z]alloc and kmem_cache_free) to initializing all the fields. We want to unify this in order to end up having some unified initialization of the vmas, and the first step to this is to at least have basic allocation functions. Right now those functions are literally just wrappers around the kmem_cache_*() calls. This is a purely mechanical conversion: # new vma: kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL) -> vm_area_alloc() # copy old vma kmem_cache_alloc(vm_area_cachep, GFP_KERNEL) -> vm_area_dup(old) # free vma kmem_cache_free(vm_area_cachep, vma) -> vm_area_free(vma) to the point where the old vma passed in to the vm_area_dup() function isn't even used yet (because I've left all the old manual initialization alone). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/ia64/kernel/perfmon.c4
-rw-r--r--arch/ia64/mm/init.c8
-rw-r--r--fs/exec.c4
-rw-r--r--include/linux/mm.h4
-rw-r--r--kernel/fork.c21
-rw-r--r--mm/mmap.c22
-rw-r--r--mm/nommu.c8
7 files changed, 44 insertions, 27 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 3b38c717008a..e859246badca 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2278,7 +2278,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
2278 DPRINT(("smpl_buf @%p\n", smpl_buf)); 2278 DPRINT(("smpl_buf @%p\n", smpl_buf));
2279 2279
2280 /* allocate vma */ 2280 /* allocate vma */
2281 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 2281 vma = vm_area_alloc();
2282 if (!vma) { 2282 if (!vma) {
2283 DPRINT(("Cannot allocate vma\n")); 2283 DPRINT(("Cannot allocate vma\n"));
2284 goto error_kmem; 2284 goto error_kmem;
@@ -2346,7 +2346,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
2346 return 0; 2346 return 0;
2347 2347
2348error: 2348error:
2349 kmem_cache_free(vm_area_cachep, vma); 2349 vm_area_free(vma);
2350error_kmem: 2350error_kmem:
2351 pfm_rvfree(smpl_buf, size); 2351 pfm_rvfree(smpl_buf, size);
2352 2352
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 18278b448530..3f2321bffb72 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -114,7 +114,7 @@ ia64_init_addr_space (void)
114 * the problem. When the process attempts to write to the register backing store 114 * the problem. When the process attempts to write to the register backing store
115 * for the first time, it will get a SEGFAULT in this case. 115 * for the first time, it will get a SEGFAULT in this case.
116 */ 116 */
117 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 117 vma = vm_area_alloc();
118 if (vma) { 118 if (vma) {
119 INIT_LIST_HEAD(&vma->anon_vma_chain); 119 INIT_LIST_HEAD(&vma->anon_vma_chain);
120 vma->vm_mm = current->mm; 120 vma->vm_mm = current->mm;
@@ -125,7 +125,7 @@ ia64_init_addr_space (void)
125 down_write(&current->mm->mmap_sem); 125 down_write(&current->mm->mmap_sem);
126 if (insert_vm_struct(current->mm, vma)) { 126 if (insert_vm_struct(current->mm, vma)) {
127 up_write(&current->mm->mmap_sem); 127 up_write(&current->mm->mmap_sem);
128 kmem_cache_free(vm_area_cachep, vma); 128 vm_area_free(vma);
129 return; 129 return;
130 } 130 }
131 up_write(&current->mm->mmap_sem); 131 up_write(&current->mm->mmap_sem);
@@ -133,7 +133,7 @@ ia64_init_addr_space (void)
133 133
134 /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */ 134 /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
135 if (!(current->personality & MMAP_PAGE_ZERO)) { 135 if (!(current->personality & MMAP_PAGE_ZERO)) {
136 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 136 vma = vm_area_alloc();
137 if (vma) { 137 if (vma) {
138 INIT_LIST_HEAD(&vma->anon_vma_chain); 138 INIT_LIST_HEAD(&vma->anon_vma_chain);
139 vma->vm_mm = current->mm; 139 vma->vm_mm = current->mm;
@@ -144,7 +144,7 @@ ia64_init_addr_space (void)
144 down_write(&current->mm->mmap_sem); 144 down_write(&current->mm->mmap_sem);
145 if (insert_vm_struct(current->mm, vma)) { 145 if (insert_vm_struct(current->mm, vma)) {
146 up_write(&current->mm->mmap_sem); 146 up_write(&current->mm->mmap_sem);
147 kmem_cache_free(vm_area_cachep, vma); 147 vm_area_free(vma);
148 return; 148 return;
149 } 149 }
150 up_write(&current->mm->mmap_sem); 150 up_write(&current->mm->mmap_sem);
diff --git a/fs/exec.c b/fs/exec.c
index 2d4e0075bd24..9bd83989ea25 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -290,7 +290,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
290 struct vm_area_struct *vma = NULL; 290 struct vm_area_struct *vma = NULL;
291 struct mm_struct *mm = bprm->mm; 291 struct mm_struct *mm = bprm->mm;
292 292
293 bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 293 bprm->vma = vma = vm_area_alloc();
294 if (!vma) 294 if (!vma)
295 return -ENOMEM; 295 return -ENOMEM;
296 296
@@ -326,7 +326,7 @@ err:
326 up_write(&mm->mmap_sem); 326 up_write(&mm->mmap_sem);
327err_free: 327err_free:
328 bprm->vma = NULL; 328 bprm->vma = NULL;
329 kmem_cache_free(vm_area_cachep, vma); 329 vm_area_free(vma);
330 return err; 330 return err;
331} 331}
332 332
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 3982c83fdcbf..de2fd86c6154 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -155,7 +155,9 @@ extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *,
155 * mmap() functions). 155 * mmap() functions).
156 */ 156 */
157 157
158extern struct kmem_cache *vm_area_cachep; 158struct vm_area_struct *vm_area_alloc(void);
159struct vm_area_struct *vm_area_dup(struct vm_area_struct *);
160void vm_area_free(struct vm_area_struct *);
159 161
160#ifndef CONFIG_MMU 162#ifndef CONFIG_MMU
161extern struct rb_root nommu_region_tree; 163extern struct rb_root nommu_region_tree;
diff --git a/kernel/fork.c b/kernel/fork.c
index 9440d61b925c..0e23deb5acfc 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -303,11 +303,26 @@ struct kmem_cache *files_cachep;
303struct kmem_cache *fs_cachep; 303struct kmem_cache *fs_cachep;
304 304
305/* SLAB cache for vm_area_struct structures */ 305/* SLAB cache for vm_area_struct structures */
306struct kmem_cache *vm_area_cachep; 306static struct kmem_cache *vm_area_cachep;
307 307
308/* SLAB cache for mm_struct structures (tsk->mm) */ 308/* SLAB cache for mm_struct structures (tsk->mm) */
309static struct kmem_cache *mm_cachep; 309static struct kmem_cache *mm_cachep;
310 310
311struct vm_area_struct *vm_area_alloc(void)
312{
313 return kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
314}
315
316struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
317{
318 return kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
319}
320
321void vm_area_free(struct vm_area_struct *vma)
322{
323 kmem_cache_free(vm_area_cachep, vma);
324}
325
311static void account_kernel_stack(struct task_struct *tsk, int account) 326static void account_kernel_stack(struct task_struct *tsk, int account)
312{ 327{
313 void *stack = task_stack_page(tsk); 328 void *stack = task_stack_page(tsk);
@@ -455,7 +470,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
455 goto fail_nomem; 470 goto fail_nomem;
456 charge = len; 471 charge = len;
457 } 472 }
458 tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); 473 tmp = vm_area_dup(mpnt);
459 if (!tmp) 474 if (!tmp)
460 goto fail_nomem; 475 goto fail_nomem;
461 *tmp = *mpnt; 476 *tmp = *mpnt;
@@ -539,7 +554,7 @@ fail_uprobe_end:
539fail_nomem_anon_vma_fork: 554fail_nomem_anon_vma_fork:
540 mpol_put(vma_policy(tmp)); 555 mpol_put(vma_policy(tmp));
541fail_nomem_policy: 556fail_nomem_policy:
542 kmem_cache_free(vm_area_cachep, tmp); 557 vm_area_free(tmp);
543fail_nomem: 558fail_nomem:
544 retval = -ENOMEM; 559 retval = -ENOMEM;
545 vm_unacct_memory(charge); 560 vm_unacct_memory(charge);
diff --git a/mm/mmap.c b/mm/mmap.c
index 5801b5f0a634..4286ad2dd1f5 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -182,7 +182,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
182 if (vma->vm_file) 182 if (vma->vm_file)
183 fput(vma->vm_file); 183 fput(vma->vm_file);
184 mpol_put(vma_policy(vma)); 184 mpol_put(vma_policy(vma));
185 kmem_cache_free(vm_area_cachep, vma); 185 vm_area_free(vma);
186 return next; 186 return next;
187} 187}
188 188
@@ -911,7 +911,7 @@ again:
911 anon_vma_merge(vma, next); 911 anon_vma_merge(vma, next);
912 mm->map_count--; 912 mm->map_count--;
913 mpol_put(vma_policy(next)); 913 mpol_put(vma_policy(next));
914 kmem_cache_free(vm_area_cachep, next); 914 vm_area_free(next);
915 /* 915 /*
916 * In mprotect's case 6 (see comments on vma_merge), 916 * In mprotect's case 6 (see comments on vma_merge),
917 * we must remove another next too. It would clutter 917 * we must remove another next too. It would clutter
@@ -1729,7 +1729,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
1729 * specific mapper. the address has already been validated, but 1729 * specific mapper. the address has already been validated, but
1730 * not unmapped, but the maps are removed from the list. 1730 * not unmapped, but the maps are removed from the list.
1731 */ 1731 */
1732 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 1732 vma = vm_area_alloc();
1733 if (!vma) { 1733 if (!vma) {
1734 error = -ENOMEM; 1734 error = -ENOMEM;
1735 goto unacct_error; 1735 goto unacct_error;
@@ -1832,7 +1832,7 @@ allow_write_and_free_vma:
1832 if (vm_flags & VM_DENYWRITE) 1832 if (vm_flags & VM_DENYWRITE)
1833 allow_write_access(file); 1833 allow_write_access(file);
1834free_vma: 1834free_vma:
1835 kmem_cache_free(vm_area_cachep, vma); 1835 vm_area_free(vma);
1836unacct_error: 1836unacct_error:
1837 if (charged) 1837 if (charged)
1838 vm_unacct_memory(charged); 1838 vm_unacct_memory(charged);
@@ -2620,7 +2620,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
2620 return err; 2620 return err;
2621 } 2621 }
2622 2622
2623 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); 2623 new = vm_area_dup(vma);
2624 if (!new) 2624 if (!new)
2625 return -ENOMEM; 2625 return -ENOMEM;
2626 2626
@@ -2669,7 +2669,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
2669 out_free_mpol: 2669 out_free_mpol:
2670 mpol_put(vma_policy(new)); 2670 mpol_put(vma_policy(new));
2671 out_free_vma: 2671 out_free_vma:
2672 kmem_cache_free(vm_area_cachep, new); 2672 vm_area_free(new);
2673 return err; 2673 return err;
2674} 2674}
2675 2675
@@ -2984,7 +2984,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla
2984 /* 2984 /*
2985 * create a vma struct for an anonymous mapping 2985 * create a vma struct for an anonymous mapping
2986 */ 2986 */
2987 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 2987 vma = vm_area_alloc();
2988 if (!vma) { 2988 if (!vma) {
2989 vm_unacct_memory(len >> PAGE_SHIFT); 2989 vm_unacct_memory(len >> PAGE_SHIFT);
2990 return -ENOMEM; 2990 return -ENOMEM;
@@ -3202,7 +3202,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
3202 } 3202 }
3203 *need_rmap_locks = (new_vma->vm_pgoff <= vma->vm_pgoff); 3203 *need_rmap_locks = (new_vma->vm_pgoff <= vma->vm_pgoff);
3204 } else { 3204 } else {
3205 new_vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); 3205 new_vma = vm_area_dup(vma);
3206 if (!new_vma) 3206 if (!new_vma)
3207 goto out; 3207 goto out;
3208 *new_vma = *vma; 3208 *new_vma = *vma;
@@ -3226,7 +3226,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
3226out_free_mempol: 3226out_free_mempol:
3227 mpol_put(vma_policy(new_vma)); 3227 mpol_put(vma_policy(new_vma));
3228out_free_vma: 3228out_free_vma:
3229 kmem_cache_free(vm_area_cachep, new_vma); 3229 vm_area_free(new_vma);
3230out: 3230out:
3231 return NULL; 3231 return NULL;
3232} 3232}
@@ -3350,7 +3350,7 @@ static struct vm_area_struct *__install_special_mapping(
3350 int ret; 3350 int ret;
3351 struct vm_area_struct *vma; 3351 struct vm_area_struct *vma;
3352 3352
3353 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 3353 vma = vm_area_alloc();
3354 if (unlikely(vma == NULL)) 3354 if (unlikely(vma == NULL))
3355 return ERR_PTR(-ENOMEM); 3355 return ERR_PTR(-ENOMEM);
3356 3356
@@ -3376,7 +3376,7 @@ static struct vm_area_struct *__install_special_mapping(
3376 return vma; 3376 return vma;
3377 3377
3378out: 3378out:
3379 kmem_cache_free(vm_area_cachep, vma); 3379 vm_area_free(vma);
3380 return ERR_PTR(ret); 3380 return ERR_PTR(ret);
3381} 3381}
3382 3382
diff --git a/mm/nommu.c b/mm/nommu.c
index 4452d8bd9ae4..006e3fe65017 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -769,7 +769,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
769 if (vma->vm_file) 769 if (vma->vm_file)
770 fput(vma->vm_file); 770 fput(vma->vm_file);
771 put_nommu_region(vma->vm_region); 771 put_nommu_region(vma->vm_region);
772 kmem_cache_free(vm_area_cachep, vma); 772 vm_area_free(vma);
773} 773}
774 774
775/* 775/*
@@ -1204,7 +1204,7 @@ unsigned long do_mmap(struct file *file,
1204 if (!region) 1204 if (!region)
1205 goto error_getting_region; 1205 goto error_getting_region;
1206 1206
1207 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 1207 vma = vm_area_alloc();
1208 if (!vma) 1208 if (!vma)
1209 goto error_getting_vma; 1209 goto error_getting_vma;
1210 1210
@@ -1368,7 +1368,7 @@ error:
1368 kmem_cache_free(vm_region_jar, region); 1368 kmem_cache_free(vm_region_jar, region);
1369 if (vma->vm_file) 1369 if (vma->vm_file)
1370 fput(vma->vm_file); 1370 fput(vma->vm_file);
1371 kmem_cache_free(vm_area_cachep, vma); 1371 vm_area_free(vma);
1372 return ret; 1372 return ret;
1373 1373
1374sharing_violation: 1374sharing_violation:
@@ -1469,7 +1469,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
1469 if (!region) 1469 if (!region)
1470 return -ENOMEM; 1470 return -ENOMEM;
1471 1471
1472 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); 1472 new = vm_area_dup(vma);
1473 if (!new) { 1473 if (!new) {
1474 kmem_cache_free(vm_region_jar, region); 1474 kmem_cache_free(vm_region_jar, region);
1475 return -ENOMEM; 1475 return -ENOMEM;