[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 9 Sep 2022 16:38:27 +0200
From: Laurent Dufour <ldufour@...ux.ibm.com>
To: Suren Baghdasaryan <surenb@...gle.com>, akpm@...ux-foundation.org
Cc: michel@...pinasse.org, jglisse@...gle.com, mhocko@...e.com,
vbabka@...e.cz, hannes@...xchg.org, mgorman@...e.de,
dave@...olabs.net, willy@...radead.org, liam.howlett@...cle.com,
peterz@...radead.org, laurent.dufour@...ibm.com,
paulmck@...nel.org, luto@...nel.org, songliubraving@...com,
peterx@...hat.com, david@...hat.com, dhowells@...hat.com,
hughd@...gle.com, bigeasy@...utronix.de, kent.overstreet@...ux.dev,
rientjes@...gle.com, axelrasmussen@...gle.com, joelaf@...gle.com,
minchan@...gle.com, kernel-team@...roid.com, linux-mm@...ck.org,
linux-arm-kernel@...ts.infradead.org,
linuxppc-dev@...ts.ozlabs.org, x86@...nel.org,
linux-kernel@...r.kernel.org
Subject: Re: [RFC PATCH RESEND 21/28] mm: introduce find_and_lock_anon_vma to
be used from arch-specific code
Le 01/09/2022 à 19:35, Suren Baghdasaryan a écrit :
> Introduce find_and_lock_anon_vma function to lookup and lock an anonymous
> VMA during page fault handling. When VMA is not found, can't be locked
> or changes after being locked, the function returns NULL. The lookup is
> performed under RCU protection to prevent the found VMA from being
> destroyed before the VMA lock is acquired. VMA lock statistics are
> updated according to the results.
>
> Signed-off-by: Suren Baghdasaryan <surenb@...gle.com>
> ---
> include/linux/mm.h | 3 +++
> mm/memory.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 48 insertions(+)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 7c3190eaabd7..a3cbaa7b9119 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -684,6 +684,9 @@ static inline void vma_assert_no_reader(struct vm_area_struct *vma)
> vma);
> }
>
> +struct vm_area_struct *find_and_lock_anon_vma(struct mm_struct *mm,
> + unsigned long address);
> +
> #else /* CONFIG_PER_VMA_LOCK */
>
> static inline void vma_init_lock(struct vm_area_struct *vma) {}
> diff --git a/mm/memory.c b/mm/memory.c
> index 29d2f49f922a..bf557f7056de 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -5183,6 +5183,51 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
> }
> EXPORT_SYMBOL_GPL(handle_mm_fault);
>
> +#ifdef CONFIG_PER_VMA_LOCK
> +static inline struct vm_area_struct *find_vma_under_rcu(struct mm_struct *mm,
> + unsigned long address)
> +{
> + struct vm_area_struct *vma = __find_vma(mm, address);
> +
> + if (!vma || vma->vm_start > address)
> + return NULL;
> +
> + if (!vma_is_anonymous(vma))
> + return NULL;
> +
It looks to me more natural to first check that the VMA is part of the RB
tree before try read locking it.
> + if (!vma_read_trylock(vma)) {
> + count_vm_vma_lock_event(VMA_LOCK_ABORT);
> + return NULL;
> + }
> +
> + /* Check if the VMA got isolated after we found it */
> + if (RB_EMPTY_NODE(&vma->vm_rb)) {
> + vma_read_unlock(vma);
> + count_vm_vma_lock_event(VMA_LOCK_MISS);
> + return NULL;
> + }
> +
> + return vma;
> +}
> +
> +/*
> + * Lookup and lock and anonymous VMA. Returned VMA is guaranteed to be stable
> + * and not isolated. If the VMA is not found of is being modified the function
> + * returns NULL.
> + */
> +struct vm_area_struct *find_and_lock_anon_vma(struct mm_struct *mm,
> + unsigned long address)
> +{
> + struct vm_area_struct *vma;
> +
> + rcu_read_lock();
> + vma = find_vma_under_rcu(mm, address);
> + rcu_read_unlock();
> +
> + return vma;
> +}
> +#endif /* CONFIG_PER_VMA_LOCK */
> +
> #ifndef __PAGETABLE_P4D_FOLDED
> /*
> * Allocate p4d page table.
Powered by blists - more mailing lists