Commit 20cce633 authored by Michel Lespinasse's avatar Michel Lespinasse Committed by Andrew Morton

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.comSigned-off-by: default avatarMichel Lespinasse <michel@lespinasse.org>
Signed-off-by: default avatarSuren Baghdasaryan <surenb@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 0b6cc04f
...@@ -480,9 +480,16 @@ struct anon_vma_name { ...@@ -480,9 +480,16 @@ struct anon_vma_name {
struct vm_area_struct { struct vm_area_struct {
/* The first cache line has the info for VMA tree walking. */ /* The first cache line has the info for VMA tree walking. */
unsigned long vm_start; /* Our start address within vm_mm. */ union {
unsigned long vm_end; /* The first byte after our end address struct {
within vm_mm. */ /* VMA covers [vm_start; vm_end) addresses within mm */
unsigned long vm_start;
unsigned long vm_end;
};
#ifdef CONFIG_PER_VMA_LOCK
struct rcu_head vm_rcu; /* Used for deferred freeing. */
#endif
};
struct mm_struct *vm_mm; /* The address space we belong to. */ struct mm_struct *vm_mm; /* The address space we belong to. */
pgprot_t vm_page_prot; /* Access permissions of this VMA. */ pgprot_t vm_page_prot; /* Access permissions of this VMA. */
......
...@@ -479,12 +479,30 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) ...@@ -479,12 +479,30 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
return new; 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); free_anon_vma_name(vma);
kmem_cache_free(vm_area_cachep, 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) static void account_kernel_stack(struct task_struct *tsk, int account)
{ {
if (IS_ENABLED(CONFIG_VMAP_STACK)) { if (IS_ENABLED(CONFIG_VMAP_STACK)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment