From: "Liam R. Howlett" <liam.howl...@oracle.com>

Use the maple tree in RCU mode for VMA tracking.  This is necessary for
the use of per-VMA locking.  RCU mode is enabled by default but disabled
when exiting an mm and for the new tree during a fork.

Also enable RCU for the tree used in munmap operations to ensure the
nodes remain valid for readers.

Signed-off-by: Liam R. Howlett <liam.howl...@oracle.com>
Signed-off-by: Suren Baghdasaryan <sur...@google.com>
---
 include/linux/mm_types.h | 3 ++-
 kernel/fork.c            | 3 +++
 mm/mmap.c                | 4 +++-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index da983aedb741..8410c3052148 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -768,7 +768,8 @@ struct mm_struct {
        unsigned long cpu_bitmap[];
 };
 
-#define MM_MT_FLAGS    (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN)
+#define MM_MT_FLAGS    (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
+                        MT_FLAGS_USE_RCU)
 extern struct mm_struct init_mm;
 
 /* Pointer magic because the dynamic array size confuses some compilers. */
diff --git a/kernel/fork.c b/kernel/fork.c
index 5e3029ea8e1e..5f23d5e03362 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -617,6 +617,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
        if (retval)
                goto out;
 
+       mt_clear_in_rcu(vmi.mas.tree);
        for_each_vma(old_vmi, mpnt) {
                struct file *file;
 
@@ -700,6 +701,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
        retval = arch_dup_mmap(oldmm, mm);
 loop_out:
        vma_iter_free(&vmi);
+       if (!retval)
+               mt_set_in_rcu(vmi.mas.tree);
 out:
        mmap_write_unlock(mm);
        flush_tlb_mm(oldmm);
diff --git a/mm/mmap.c b/mm/mmap.c
index 9d0dadb55e9a..9efe13d36df7 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2277,7 +2277,8 @@ do_vmi_align_munmap(struct vma_iterator *vmi, struct 
vm_area_struct *vma,
        int count = 0;
        int error = -ENOMEM;
        MA_STATE(mas_detach, &mt_detach, 0, 0);
-       mt_init_flags(&mt_detach, MT_FLAGS_LOCK_EXTERN);
+       mt_init_flags(&mt_detach, vmi->mas.tree->ma_flags &
+                     (MT_FLAGS_LOCK_MASK | MT_FLAGS_USE_RCU));
        mt_set_external_lock(&mt_detach, &mm->mmap_lock);
 
        /*
@@ -3042,6 +3043,7 @@ void exit_mmap(struct mm_struct *mm)
         */
        set_bit(MMF_OOM_SKIP, &mm->flags);
        mmap_write_lock(mm);
+       mt_clear_in_rcu(&mm->mm_mt);
        free_pgtables(&tlb, &mm->mm_mt, vma, FIRST_USER_ADDRESS,
                      USER_PGTABLES_CEILING);
        tlb_finish_mmu(&tlb);
-- 
2.39.1

Reply via email to