Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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