* [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
@ 2026-09-16 4:31 Kefeng Wang
2026-09-16 6:33 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 6+ messages in thread
From: Kefeng Wang @ 2026-09-16 4:31 UTC (permalink / raw)
To: Andrew Morton, linux-mm
Cc: Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, David Hildenbrand, Zi Yan, Kefeng Wang
do_mincore() performs a read-only, per-VMA residency query,
making it a good candidate for per-VMA locking. Convert it
to acquire the per-VMA lock, thereby reducing contention on
the per-MM mmap_lock.
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
v3:
- add vma_assert_locked, update changelog/comment, per David
- Add RB
v2, (RESEND):
- using new vma_start_read_unlocked() API, suggestted by Pedro Falcato
v1:
- https://lore.kernel.org/linux-mm/20260701144047.3786939-2-wangkefeng.wang@huawei.com/
mm/mincore.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/mm/mincore.c b/mm/mincore.c
index c086836bc4bc..0fe50f8a7e62 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -235,24 +235,22 @@ static const struct mm_walk_ops mincore_walk_ops = {
.pmd_entry = mincore_pte_range,
.pte_hole = mincore_unmapped_range,
.hugetlb_entry = mincore_hugetlb,
- .walk_lock = PGWALK_RDLOCK,
+ .walk_lock = PGWALK_VMA_RDLOCK_VERIFY,
};
/*
* Do a chunk of "sys_mincore()". We've already checked
- * all the arguments, we hold the mmap semaphore: we should
+ * all the arguments, we hold the VMA read lock: we should
* just return the amount of info we're asked for.
*/
-static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *vec)
+static long do_mincore(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long pages, unsigned char *vec)
{
- struct vm_area_struct *vma;
- unsigned long end;
+ unsigned long end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
int err;
- vma = vma_lookup(current->mm, addr);
- if (!vma)
- return -ENOMEM;
- end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
+ vma_assert_locked(vma);
+
if (!can_do_mincore(vma)) {
unsigned long pages = DIV_ROUND_UP(end - addr, PAGE_SIZE);
memset(vec, 1, pages);
@@ -319,13 +317,20 @@ SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len,
retval = 0;
while (pages) {
+ struct vm_area_struct *vma;
+
+ vma = vma_start_read_unlocked(current->mm, start);
+ if (!vma) {
+ retval = -ENOMEM;
+ break;
+ }
+
/*
* Do at most PAGE_SIZE entries per iteration, due to
* the temporary buffer size.
*/
- mmap_read_lock(current->mm);
- retval = do_mincore(start, min(pages, PAGE_SIZE), tmp);
- mmap_read_unlock(current->mm);
+ retval = do_mincore(vma, start, min(pages, PAGE_SIZE), tmp);
+ vma_end_read(vma);
if (retval <= 0)
break;
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
2026-09-16 4:31 [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk Kefeng Wang
@ 2026-09-16 6:33 ` David Hildenbrand (Arm)
2026-09-16 6:50 ` Kefeng Wang
0 siblings, 1 reply; 6+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-16 6:33 UTC (permalink / raw)
To: Kefeng Wang, Andrew Morton, linux-mm
Cc: Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Zi Yan
On 9/16/26 06:31, Kefeng Wang wrote:
> do_mincore() performs a read-only, per-VMA residency query,
> making it a good candidate for per-VMA locking. Convert it
> to acquire the per-VMA lock, thereby reducing contention on
> the per-MM mmap_lock.
>
> Reviewed-by: Pedro Falcato <pfalcato@suse.de>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
> v3:
> - add vma_assert_locked, update changelog/comment, per David
It likely was Lorenzo :)
> - Add RB
> v2, (RESEND):
> - using new vma_start_read_unlocked() API, suggestted by Pedro Falcato
> v1:
> - https://lore.kernel.org/linux-mm/20260701144047.3786939-2-wangkefeng.wang@huawei.com/
>
> mm/mincore.c | 29 +++++++++++++++++------------
> 1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/mm/mincore.c b/mm/mincore.c
> index c086836bc4bc..0fe50f8a7e62 100644
> --- a/mm/mincore.c
> +++ b/mm/mincore.c
> @@ -235,24 +235,22 @@ static const struct mm_walk_ops mincore_walk_ops = {
> .pmd_entry = mincore_pte_range,
> .pte_hole = mincore_unmapped_range,
> .hugetlb_entry = mincore_hugetlb,
> - .walk_lock = PGWALK_RDLOCK,
> + .walk_lock = PGWALK_VMA_RDLOCK_VERIFY,
> };
>
> /*
> * Do a chunk of "sys_mincore()". We've already checked
> - * all the arguments, we hold the mmap semaphore: we should
> + * all the arguments, we hold the VMA read lock: we should
> * just return the amount of info we're asked for.
> */
> -static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *vec)
> +static long do_mincore(struct vm_area_struct *vma, unsigned long addr,
> + unsigned long pages, unsigned char *vec)
> {
> - struct vm_area_struct *vma;
> - unsigned long end;
> + unsigned long end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
> int err;
>
> - vma = vma_lookup(current->mm, addr);
> - if (!vma)
> - return -ENOMEM;
> - end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
> + vma_assert_locked(vma);
I think Lorenzo asked whether we should do that. But the walk_page_vma() further
below would already verify that due to PGWALK_VMA_RDLOCK_VERIFY (see
process_vma_walk_lock) so not sure if that's really required here.
AFAIKS, everything we do in mincore_pte_range() should be compatible with the
VMA lock, including the swap and pagecache handling.
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
2026-09-16 6:33 ` David Hildenbrand (Arm)
@ 2026-09-16 6:50 ` Kefeng Wang
2026-09-16 11:19 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 6+ messages in thread
From: Kefeng Wang @ 2026-09-16 6:50 UTC (permalink / raw)
To: David Hildenbrand (Arm), Andrew Morton, linux-mm
Cc: Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Zi Yan
On 9/16/2026 2:33 PM, David Hildenbrand (Arm) wrote:
> On 9/16/26 06:31, Kefeng Wang wrote:
>> do_mincore() performs a read-only, per-VMA residency query,
>> making it a good candidate for per-VMA locking. Convert it
>> to acquire the per-VMA lock, thereby reducing contention on
>> the per-MM mmap_lock.
>>
>> Reviewed-by: Pedro Falcato <pfalcato@suse.de>
>> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
>> ---
>> v3:
>> - add vma_assert_locked, update changelog/comment, per David
>
> It likely was Lorenzo :)
>
Oh, I'm completely blind :)
>> - Add RB
>> v2, (RESEND):
>> - using new vma_start_read_unlocked() API, suggestted by Pedro Falcato
>> v1:
>> - https://lore.kernel.org/linux-mm/20260701144047.3786939-2-wangkefeng.wang@huawei.com/
>>
>> mm/mincore.c | 29 +++++++++++++++++------------
>> 1 file changed, 17 insertions(+), 12 deletions(-)
>>
>> diff --git a/mm/mincore.c b/mm/mincore.c
>> index c086836bc4bc..0fe50f8a7e62 100644
>> --- a/mm/mincore.c
>> +++ b/mm/mincore.c
>> @@ -235,24 +235,22 @@ static const struct mm_walk_ops mincore_walk_ops = {
>> .pmd_entry = mincore_pte_range,
>> .pte_hole = mincore_unmapped_range,
>> .hugetlb_entry = mincore_hugetlb,
>> - .walk_lock = PGWALK_RDLOCK,
>> + .walk_lock = PGWALK_VMA_RDLOCK_VERIFY,
>> };
>>
>> /*
>> * Do a chunk of "sys_mincore()". We've already checked
>> - * all the arguments, we hold the mmap semaphore: we should
>> + * all the arguments, we hold the VMA read lock: we should
>> * just return the amount of info we're asked for.
>> */
>> -static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *vec)
>> +static long do_mincore(struct vm_area_struct *vma, unsigned long addr,
>> + unsigned long pages, unsigned char *vec)
>> {
>> - struct vm_area_struct *vma;
>> - unsigned long end;
>> + unsigned long end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
>> int err;
>>
>> - vma = vma_lookup(current->mm, addr);
>> - if (!vma)
>> - return -ENOMEM;
>> - end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
>> + vma_assert_locked(vma);
>
> I think Lorenzo asked whether we should do that. But the walk_page_vma() further
> below would already verify that due to PGWALK_VMA_RDLOCK_VERIFY (see
> process_vma_walk_lock) so not sure if that's really required here.
I misunderstood Lorenzo's intention, which has already been verified
through the PGWALK_VMA_RDLOCK_VERIFY check. I don't think it has much
value, but adding it doesn't do any harm.
>
> AFAIKS, everything we do in mincore_pte_range() should be compatible with the
> VMA lock, including the swap and pagecache handling.
>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
>
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
2026-09-16 6:50 ` Kefeng Wang
@ 2026-09-16 11:19 ` Lorenzo Stoakes (ARM)
2026-09-16 12:30 ` Pedro Falcato
0 siblings, 1 reply; 6+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-09-16 11:19 UTC (permalink / raw)
To: Kefeng Wang
Cc: David Hildenbrand (Arm), Andrew Morton, linux-mm, Liam R. Howlett,
Vlastimil Babka, Jann Horn, Pedro Falcato, Zi Yan
On Wed, Sep 16, 2026 at 02:50:17PM +0800, Kefeng Wang wrote:
>
>
> On 9/16/2026 2:33 PM, David Hildenbrand (Arm) wrote:
> > On 9/16/26 06:31, Kefeng Wang wrote:
> > > do_mincore() performs a read-only, per-VMA residency query,
> > > making it a good candidate for per-VMA locking. Convert it
> > > to acquire the per-VMA lock, thereby reducing contention on
> > > the per-MM mmap_lock.
> > >
> > > Reviewed-by: Pedro Falcato <pfalcato@suse.de>
> > > Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
LGTM so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> > > ---
> > > v3:
> > > - add vma_assert_locked, update changelog/comment, per David
> >
> > It likely was Lorenzo :)
> >
>
> Oh, I'm completely blind :)
>
> > > - Add RB
> > > v2, (RESEND):
> > > - using new vma_start_read_unlocked() API, suggestted by Pedro Falcato
> > > v1:
> > > - https://lore.kernel.org/linux-mm/20260701144047.3786939-2-wangkefeng.wang@huawei.com/
> > >
> > > mm/mincore.c | 29 +++++++++++++++++------------
> > > 1 file changed, 17 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/mm/mincore.c b/mm/mincore.c
> > > index c086836bc4bc..0fe50f8a7e62 100644
> > > --- a/mm/mincore.c
> > > +++ b/mm/mincore.c
> > > @@ -235,24 +235,22 @@ static const struct mm_walk_ops mincore_walk_ops = {
> > > .pmd_entry = mincore_pte_range,
> > > .pte_hole = mincore_unmapped_range,
> > > .hugetlb_entry = mincore_hugetlb,
> > > - .walk_lock = PGWALK_RDLOCK,
> > > + .walk_lock = PGWALK_VMA_RDLOCK_VERIFY,
> > > };
> > > /*
> > > * Do a chunk of "sys_mincore()". We've already checked
> > > - * all the arguments, we hold the mmap semaphore: we should
> > > + * all the arguments, we hold the VMA read lock: we should
> > > * just return the amount of info we're asked for.
> > > */
> > > -static long do_mincore(unsigned long addr, unsigned long pages, unsigned char *vec)
> > > +static long do_mincore(struct vm_area_struct *vma, unsigned long addr,
> > > + unsigned long pages, unsigned char *vec)
> > > {
> > > - struct vm_area_struct *vma;
> > > - unsigned long end;
> > > + unsigned long end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
> > > int err;
> > > - vma = vma_lookup(current->mm, addr);
> > > - if (!vma)
> > > - return -ENOMEM;
> > > - end = min(vma->vm_end, addr + (pages << PAGE_SHIFT));
> > > + vma_assert_locked(vma);
> >
> > I think Lorenzo asked whether we should do that. But the walk_page_vma() further
> > below would already verify that due to PGWALK_VMA_RDLOCK_VERIFY (see
> > process_vma_walk_lock) so not sure if that's really required here.
That happens after you do actions which require the lock.
>
> I misunderstood Lorenzo's intention, which has already been verified through
> the PGWALK_VMA_RDLOCK_VERIFY check. I don't think it has much value, but
> adding it doesn't do any harm.
...! I mean, the polite thing might be to ask? :)
It's not critical, since you literally take it immediately prior to calling
do_mincore().
But I felt it'd be a nice, self-contained, self-documenting way of
establishing the invariant given you just changed the function.
However you're also commenting that so it's not vital.
>
> >
> > AFAIKS, everything we do in mincore_pte_range() should be compatible with the
> > VMA lock, including the swap and pagecache handling.
It'd be pretty broken if the VMA lock provided less guarantees than the
mmap read lock in VMA-specific operations.
> >
> > Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> >
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
2026-09-16 11:19 ` Lorenzo Stoakes (ARM)
@ 2026-09-16 12:30 ` Pedro Falcato
2026-09-16 12:40 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 6+ messages in thread
From: Pedro Falcato @ 2026-09-16 12:30 UTC (permalink / raw)
To: Lorenzo Stoakes (ARM)
Cc: Kefeng Wang, David Hildenbrand (Arm), Andrew Morton, linux-mm,
Liam R. Howlett, Vlastimil Babka, Jann Horn, Zi Yan
On Wed, Sep 16, 2026 at 12:19:50PM +0100, Lorenzo Stoakes (ARM) wrote:
> <snip>
> It'd be pretty broken if the VMA lock provided less guarantees than the
> mmap read lock in VMA-specific operations.
Well, there is one big case where that doesn't happen: cross-VMA operations.
For which ATM there is no locking scheme for "lock two or more VMAs" so any
operation loses atomicity.
Which isn't a problem here, because mincore() seems to have been written in
a silly way.
--
Pedro
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk
2026-09-16 12:30 ` Pedro Falcato
@ 2026-09-16 12:40 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-09-16 12:40 UTC (permalink / raw)
To: Pedro Falcato
Cc: Kefeng Wang, David Hildenbrand (Arm), Andrew Morton, linux-mm,
Liam R. Howlett, Vlastimil Babka, Jann Horn, Zi Yan
On Wed, Sep 16, 2026 at 01:30:53PM +0100, Pedro Falcato wrote:
> On Wed, Sep 16, 2026 at 12:19:50PM +0100, Lorenzo Stoakes (ARM) wrote:
> > <snip>
> > It'd be pretty broken if the VMA lock provided less guarantees than the
> > mmap read lock in VMA-specific operations.
>
> Well, there is one big case where that doesn't happen: cross-VMA operations.
> For which ATM there is no locking scheme for "lock two or more VMAs" so any
> operation loses atomicity.
Right yeah :)
I meant at a VMA granularity.
The /proc/$pid/maps stuff that Suren is doing speaks to the difficulties you
encounter when acquiring a VMA lock over a range of VMAs.
>
> Which isn't a problem here, because mincore() seems to have been written in
> a silly way.
I saw that it was explicitly limited to a single VMA so I wasn't worried about
it ;)
>
> --
> Pedro
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-16 12:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-16 4:31 [PATCH mm-new v3] mm: mincore: use per-vma lock during page table walk Kefeng Wang
2026-09-16 6:33 ` David Hildenbrand (Arm)
2026-09-16 6:50 ` Kefeng Wang
2026-09-16 11:19 ` Lorenzo Stoakes (ARM)
2026-09-16 12:30 ` Pedro Falcato
2026-09-16 12:40 ` Lorenzo Stoakes (ARM)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox