This is a note to let you know that I've just added the patch titled fork: lock VMAs of the parent process when forking, again to the 6.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: fork-lock-vmas-of-the-parent-process-when-forking-again.patch and it can be found in the queue-6.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From fb49c455323ff8319a123dd312be9082c49a23a5 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan <surenb@xxxxxxxxxx> Date: Sat, 8 Jul 2023 12:12:12 -0700 Subject: fork: lock VMAs of the parent process when forking, again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Suren Baghdasaryan <surenb@xxxxxxxxxx> commit fb49c455323ff8319a123dd312be9082c49a23a5 upstream. When forking a child process, the parent write-protects anonymous pages and COW-shares them with the child being forked using copy_present_pte(). We must not take any concurrent page faults on the source vma's as they are being processed, as we expect both the vma and the pte's behind it to be stable. For example, the anon_vma_fork() expects the parents vma->anon_vma to not change during the vma copy. A concurrent page fault on a page newly marked read-only by the page copy might trigger wp_page_copy() and a anon_vma_prepare(vma) on the source vma, defeating the anon_vma_clone() that wasn't done because the parent vma originally didn't have an anon_vma, but we now might end up copying a pte entry for a page that has one. Before the per-vma lock based changes, the mmap_lock guaranteed exclusion with concurrent page faults. But now we need to do a vma_start_write() to make sure no concurrent faults happen on this vma while it is being processed. This fix can potentially regress some fork-heavy workloads. Kernel build time did not show noticeable regression on a 56-core machine while a stress test mapping 10000 VMAs and forking 5000 times in a tight loop shows ~5% regression. If such fork time regression is unacceptable, disabling CONFIG_PER_VMA_LOCK should restore its performance. Further optimizations are possible if this regression proves to be problematic. Suggested-by: David Hildenbrand <david@xxxxxxxxxx> Reported-by: Jiri Slaby <jirislaby@xxxxxxxxxx> Closes: https://lore.kernel.org/all/dbdef34c-3a07-5951-e1ae-e9c6e3cdf51b@xxxxxxxxxx/ Reported-by: Holger Hoffstätte <holger@xxxxxxxxxxxxxxxxxxxxxx> Closes: https://lore.kernel.org/all/b198d649-f4bf-b971-31d0-e8433ec2a34c@xxxxxxxxxxxxxxxxxxxxxx/ Reported-by: Jacob Young <jacobly.alt@xxxxxxxxx> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217624 Fixes: 0bff0aaea03e ("x86/mm: try VMA lock-based page fault handling first") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Suren Baghdasaryan <surenb@xxxxxxxxxx> Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- kernel/fork.c | 1 + 1 file changed, 1 insertion(+) --- a/kernel/fork.c +++ b/kernel/fork.c @@ -696,6 +696,7 @@ static __latent_entropy int dup_mmap(str for_each_vma(old_vmi, mpnt) { struct file *file; + vma_start_write(mpnt); if (mpnt->vm_flags & VM_DONTCOPY) { vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); continue; Patches currently in stable-queue which might be from surenb@xxxxxxxxxx are queue-6.4/fork-lock-vmas-of-the-parent-process-when-forking-again.patch queue-6.4/mm-lock-a-vma-before-stack-expansion.patch queue-6.4/mm-lock-newly-mapped-vma-with-corrected-ordering.patch queue-6.4/mm-lock-newly-mapped-vma-which-can-be-modified-after-it-becomes-visible.patch queue-6.4/fork-lock-vmas-of-the-parent-process-when-forking.patch queue-6.4/mm-disable-config_per_vma_lock-until-its-fixed.patch