diff options
author | Michel Lespinasse <michel@lespinasse.org> | 2023-02-27 18:36:09 +0100 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2023-04-06 05:02:57 +0200 |
commit | 20cce633f4254cc0df39665449726e3172518f6c (patch) | |
tree | 7988880c4a5fa5b34ffe26a7f6a9ea6af56e434d /kernel/fork.c | |
parent | mm: introduce CONFIG_PER_VMA_LOCK (diff) | |
download | linux-20cce633f4254cc0df39665449726e3172518f6c.tar.xz linux-20cce633f4254cc0df39665449726e3172518f6c.zip |
mm: rcu safe VMA freeing
This prepares for page faults handling under VMA lock, looking up VMAs
under protection of an rcu read lock, instead of the usual mmap read lock.
Link: https://lkml.kernel.org/r/20230227173632.3292573-11-surenb@google.com
Signed-off-by: Michel Lespinasse <michel@lespinasse.org>
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index cea99f003f24..93ec6e14bb65 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -479,12 +479,30 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) return new; } -void vm_area_free(struct vm_area_struct *vma) +static void __vm_area_free(struct vm_area_struct *vma) { free_anon_vma_name(vma); kmem_cache_free(vm_area_cachep, vma); } +#ifdef CONFIG_PER_VMA_LOCK +static void vm_area_free_rcu_cb(struct rcu_head *head) +{ + struct vm_area_struct *vma = container_of(head, struct vm_area_struct, + vm_rcu); + __vm_area_free(vma); +} +#endif + +void vm_area_free(struct vm_area_struct *vma) +{ +#ifdef CONFIG_PER_VMA_LOCK + call_rcu(&vma->vm_rcu, vm_area_free_rcu_cb); +#else + __vm_area_free(vma); +#endif +} + static void account_kernel_stack(struct task_struct *tsk, int account) { if (IS_ENABLED(CONFIG_VMAP_STACK)) { |