From: sashiko-bot@kernel.org
To: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>,
"David Hildenbrand" <david@kernel.org>, "Zi Yan" <ziy@nvidia.com>,
"Baolin Wang" <baolin.wang@linux.alibaba.com>,
"Liam R. Howlett" <liam@infradead.org>,
"Nico Pache" <nico.pache@linux.dev>,
"Ryan Roberts" <ryan.roberts@arm.com>,
"Dev Jain" <dev.jain@arm.com>, "Barry Song" <baohua@kernel.org>,
"Lance Yang" <lance.yang@linux.dev>,
"Usama Arif" <usama.arif@linux.dev>,
"Kiryl Shutsemau" <kas@kernel.org>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Ingo Molnar" <mingo@redhat.com>, "Will Deacon" <will@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Waiman Long" <longman@redhat.com>,
"Suren Baghdasaryan" <surenb@google.com>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Shakeel Butt" <shakeel.butt@linux.dev>,
"Yonghong Song" <yonghong.song@linux.dev>,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Song Liu" <song@kernel.org>, "Jiri Olsa" <jolsa@kernel.org>,
"Emil Tsalapatis" <emil@etsalapatis.com>,
"Ihor Solodrai" <ihor.solodrai@linux.dev>
Cc: linux-mm@kvack.org, bpf@vger.kernel.org
Subject: Re: [PATCH 5/5] mm/khugepaged: drop/reacquire mmap read lock if skipped enough VMAs
Date: Tue, 03 Nov 2026 08:49:25 +0000 [thread overview]
Message-ID: <sashiko-outbox-194883@kernel.org> (raw)
In-Reply-To: <20261103-khugepaged-latency-fix-v1-5-a07ab16ac860@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] mm/khugepaged: vm_end ALIGN() overflow rewinds vmi in collapse_scan_mm_slot()
- [Medium] mm/khugepaged: sub-PMD VMAs bypass skip batching in collapse_scan_mm_slot()
--
commit 0a737288374fc8ce4ac1b20ac082b7190ad6db37
Author: Lorenzo Stoakes (ARM) <ljs@kernel.org>
mm/khugepaged: drop/reacquire mmap read lock if skipped enough VMAs
This commit drops and reacquires the mmap read lock using
mmap_read_lock_nosteal() in collapse_scan_mm_slot() after skipping
KHUGEPAGED_MAX_SKIP_BATCH ineligible VMAs to reduce mmap_lock hold times and
relieve writer contention.
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 216c4b8d28c40..b9c72ee8b4211 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
[ ... ]
> @@ -2910,6 +2916,7 @@ static void collapse_scan_mm_slot(unsigned int progress_max,
> struct mm_struct *mm;
> struct vm_area_struct *vma;
> unsigned int progress_prev = cc->progress;
> + unsigned int skipped = 0;
>
> lockdep_assert_held(&khugepaged_mm_lock);
> *result = SCAN_FAIL;
> @@ -2951,6 +2958,14 @@ static void collapse_scan_mm_slot(unsigned int progress_max,
> /* Unable to collapse, skip to the next candidate. */
> mm_slot->address = ALIGN(vma->vm_end, HPAGE_PMD_SIZE);
> cc->progress++;
> + if (++skipped >= KHUGEPAGED_MAX_SKIP_BATCH) {
> + /* Skipped a lot of VMAs, so wait for writers. */
> + mmap_read_unlock(mm);
> + cond_resched();
> + mmap_read_lock_nosteal(mm);
> + vma_iter_set(&vmi, mm_slot->address);
> + skipped = 0;
> + }
[Severity: High]
Can mm_slot->address overflow to 0 here and cause vma_iter_set() to rewind
vmi back to the start of the address space?
On architectures where TASK_SIZE extends into the final PMD range of the
unsigned long address space, such as 64-bit s390 in
arch/s390/include/asm/processor.h:
#define TASK_SIZE (TASK_SIZE_MAX)
#define TASK_UNMAPPED_BASE (_REGION2_SIZE >> 1)
#define TASK_SIZE_MAX (-PAGE_SIZE)
a user process can map VMAs with vma->vm_end > (ULONG_MAX & HPAGE_PMD_MASK).
When collapse_scan_mm_slot() skips such a VMA,
ALIGN(vma->vm_end, HPAGE_PMD_SIZE) wraps around to 0.
If ++skipped >= KHUGEPAGED_MAX_SKIP_BATCH triggers on that VMA,
vma_iter_set(&vmi, mm_slot->address) resets the VMA iterator to address 0.
Because the !collapse_possible_orders() path does not check
cc->progress >= progress_max, if the mm contains no eligible PMD-spanning
VMAs (for example, 1024 ineligible VMAs ending in the top PMD range),
wouldn't for_each_vma(vmi, vma) restart from address 0 and loop
indefinitely inside collapse_scan_mm_slot() until the process exits or THP
is disabled?
> continue;
> }
> hstart = ALIGN(vma->vm_start, HPAGE_PMD_SIZE);
[Severity: Medium]
Should the skip batching and progress accounting also cover VMAs that pass
collapse_possible_orders() under sub-PMD mTHP but do not span a full PMD?
In mm/khugepaged.c, collapse_possible_orders() checks all enabled anonymous
mTHP orders when called with TVA_KHUGEPAGED:
static unsigned long collapse_possible_orders(struct vm_area_struct *vma,
vm_flags_t vm_flags, enum tva_type tva_flags)
{
unsigned long orders;
/* If khugepaged is scanning an anonymous vma, allow mTHP collapse */
if ((tva_flags == TVA_KHUGEPAGED) && vma_is_anonymous(vma))
orders = THP_ORDERS_ALL_ANON;
else
orders = BIT(HPAGE_PMD_ORDER);
return thp_vma_allowable_orders(vma, vm_flags, tva_flags, orders);
}
When a sub-PMD anonymous mTHP order is enabled, a faulted anonymous VMA
smaller than HPAGE_PMD_SIZE passes collapse_possible_orders(), bypassing
the !collapse_possible_orders() block in collapse_scan_mm_slot() and
falling through to:
hstart = ALIGN(vma->vm_start, HPAGE_PMD_SIZE);
hend = ALIGN_DOWN(vma->vm_end, HPAGE_PMD_SIZE);
if (mm_slot->address > hend) {
cc->progress++;
continue;
}
if (mm_slot->address < hstart)
mm_slot->address = hstart;
VM_WARN_ON_ONCE(mm_slot->address & ~HPAGE_PMD_MASK);
while (mm_slot->address < hend) {
For these sub-PMD VMAs, hstart >= hend:
- When mm_slot->address > hend, it increments cc->progress and continues
without incrementing skipped or dropping mmap_lock.
- When mm_slot->address <= hend (for instance, when a sub-PMD VMA starts on
a PMD boundary so hstart == hend == mm_slot->address, or on the first
unaligned sub-PMD VMA in a PMD range where mm_slot->address == hend <
hstart), both mm_slot->address > hend and mm_slot->address < hend are
false, so neither skipped nor cc->progress is incremented.
As a result, if an mm has a large number of small faulted anonymous VMAs
while sub-PMD mTHP is enabled, wouldn't collapse_scan_mm_slot() still walk
all of them without ever reaching KHUGEPAGED_MAX_SKIP_BATCH and dropping
mmap_lock?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261103-khugepaged-latency-fix-v1-0-a07ab16ac860@kernel.org?part=5
next prev parent reply other threads:[~2026-11-03 8:49 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 8:27 [PATCH 0/5] mm/khugepaged: bound mmap_lock hold time when walking an mm's VMAs Lorenzo Stoakes (ARM)
2026-11-03 8:27 ` [PATCH 1/5] Revert "mm/khugepaged: remove definition of struct khugepaged_mm_slot" Lorenzo Stoakes (ARM)
2026-11-04 7:46 ` Lance Yang
2026-11-05 10:17 ` David Hildenbrand (Arm)
2026-11-03 8:27 ` [PATCH 2/5] mm/khugepaged: scan mm's more efficiently under mmap_lock contention Lorenzo Stoakes (ARM)
2026-11-04 8:43 ` Lance Yang
2026-11-05 10:23 ` David Hildenbrand (Arm)
2026-11-05 14:01 ` Lorenzo Stoakes (ARM)
2026-11-03 8:27 ` [PATCH 3/5] locking/rwsem: add down_read[_killable]_nosteal() Lorenzo Stoakes (ARM)
2026-11-03 11:51 ` Peter Zijlstra
2026-11-03 12:24 ` Lorenzo Stoakes (ARM)
2026-11-05 10:25 ` David Hildenbrand (Arm)
2026-11-05 10:29 ` Lorenzo Stoakes (ARM)
2026-11-03 8:27 ` [PATCH 4/5] mm: add and use mmap_read_lock[_killable]_nosteal() on contention Lorenzo Stoakes (ARM)
2026-11-05 10:16 ` David Hildenbrand (Arm)
2026-11-05 14:02 ` Lorenzo Stoakes (ARM)
2026-11-05 16:23 ` Alexei Starovoitov
2026-11-03 8:27 ` [PATCH 5/5] mm/khugepaged: drop/reacquire mmap read lock if skipped enough VMAs Lorenzo Stoakes (ARM)
2026-11-03 8:49 ` sashiko-bot [this message]
2026-11-05 10:28 ` David Hildenbrand (Arm)
2026-11-05 14:46 ` Lorenzo Stoakes (ARM)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-194883@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=boqun@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=kas@kernel.org \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=longman@redhat.com \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=mingo@redhat.com \
--cc=nico.pache@linux.dev \
--cc=peterz@infradead.org \
--cc=ryan.roberts@arm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=song@kernel.org \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=will@kernel.org \
--cc=yonghong.song@linux.dev \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.