From 09d15944ef6235b203a1e7a60e8f3c04e50f4933 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Mon, 28 Sep 2020 15:46:55 -0400 Subject: [PATCH] kernel/fork: Stop using dup tree and pre-allocate the nodes needed. Signed-off-by: Liam R. Howlett --- kernel/fork.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 7b217b0ca234..966bc88d344f 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -471,7 +471,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, { struct vm_area_struct *mpnt, *tmp, *prev, **pprev; int retval; - unsigned long charge; + unsigned long charge = 0; MA_STATE(old_mas, &oldmm->mm_mt, 0, 0); MA_STATE(mas, &mm->mm_mt, 0, 0); LIST_HEAD(uf); @@ -506,17 +506,14 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, prev = NULL; - rcu_read_lock(); - mas_dup_tree(&old_mas, &mas); - mas_reset(&old_mas); - mas_reset(&mas); + retval = mas_entry_cnt(&mas, oldmm->map_count * 2); + if (retval) + goto fail_nomem; + mas_lock(&old_mas); mas_for_each(&old_mas, mpnt, ULONG_MAX) { struct file *file; - if (xa_is_zero(mpnt)) - continue; - if (mpnt->vm_flags & VM_DONTCOPY) { vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); continue; @@ -528,7 +525,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, */ if (fatal_signal_pending(current)) { retval = -EINTR; - goto out; + goto loop_out; } if (mpnt->vm_flags & VM_ACCOUNT) { unsigned long len = vma_pages(mpnt); @@ -593,7 +590,9 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, prev = tmp; /* Link the vma into the MT */ - mas_dup_store(&mas, tmp); + mas.index = tmp->vm_start; + mas.last = tmp->vm_end - 1; + mas_store(&mas, tmp); mm->map_count++; if (!(tmp->vm_flags & VM_WIPEONFORK)) @@ -603,12 +602,13 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, tmp->vm_ops->open(tmp); if (retval) - goto out; + goto loop_out; } /* a new mm has just been created */ retval = arch_dup_mmap(oldmm, mm); +loop_out: + mas_unlock(&old_mas); out: - rcu_read_unlock(); mmap_write_unlock(mm); flush_tlb_mm(oldmm); mmap_write_unlock(oldmm); -- 2.50.1