* [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports
@ 2026-11-05 9:52 Weilin Tong
2026-11-05 9:52 ` [PATCH 1/2] mm: kmemleak: serialize disable-time cleanup Weilin Tong
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Weilin Tong @ 2026-11-05 9:52 UTC (permalink / raw)
To: catalin.marinas, akpm; +Cc: linux-mm, linux-kernel
Reading a kmemleak report can traverse all tracked objects in one
RCU read-side section and cause a stall.
Serialize disable-time cleanup with clear operations and report readers,
then use kmemleak_cond_resched() in both report traversal loops to let RCU
progress safely during long reads.
QEMU/KVM tests on mm-stable 6628e7d4c6b25:
* With 134 million real allocations and no injected delay, continuous
RCU sections fell from 23.11-23.38 s to 126-972 us. Total reading took
23.11-23.38 s before and 23.67-24.09 s after. Neither kernel stalled.
* With identical 300 us per-node delays, only kernels without patch 2
stalled. Patch 1 eliminated overlapping cleanup entry.
* Under lazy/full preemption, 560 concurrent-removal cases, 20 deleted-chain
cases and debugfs read checks passed with KASAN, lockdep and DEBUG_LIST.
Weilin Tong (2):
mm: kmemleak: serialize disable-time cleanup
mm: kmemleak: reschedule while reading reports
mm/kmemleak.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] mm: kmemleak: serialize disable-time cleanup
2026-11-05 9:52 [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Weilin Tong
@ 2026-11-05 9:52 ` Weilin Tong
2026-11-05 9:52 ` [PATCH 2/2] mm: kmemleak: reschedule while reading reports Weilin Tong
2026-11-10 5:17 ` [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Andrew Morton
2 siblings, 0 replies; 5+ messages in thread
From: Weilin Tong @ 2026-11-05 9:52 UTC (permalink / raw)
To: catalin.marinas, akpm; +Cc: linux-mm, linux-kernel
kmemleak_do_cleanup() drops scan_mutex before removing tracked objects
without kmemleak_lock. A concurrent clear command can therefore start
another cleanup while the background cleanup is still running.
Keep scan_mutex held until the background cleanup completes, serializing
its lockless removals with explicit clearing and report readers.
Fixes: 2abd839aa7e6 ("kmemleak: Do not corrupt the object_list during clean-up")
Assisted-by: LLM
Signed-off-by: Weilin Tong <tongweilin@linux.alibaba.com>
---
mm/kmemleak.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 20c0eb41c..d959d11f6 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -2507,12 +2507,13 @@ static void kmemleak_do_cleanup(struct work_struct *work)
* function.
*/
kmemleak_free_enabled = 0;
- mutex_unlock(&scan_mutex);
+ /* Serialize the lockless cleanup with report readers. */
if (!kmemleak_found_leaks)
__kmemleak_do_cleanup();
else
pr_info("Kmemleak disabled without freeing internal data. Reclaim the memory with \"echo clear > /sys/kernel/debug/kmemleak\".\n");
+ mutex_unlock(&scan_mutex);
}
static DECLARE_WORK(cleanup_work, kmemleak_do_cleanup);
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/2] mm: kmemleak: reschedule while reading reports
2026-11-05 9:52 [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Weilin Tong
2026-11-05 9:52 ` [PATCH 1/2] mm: kmemleak: serialize disable-time cleanup Weilin Tong
@ 2026-11-05 9:52 ` Weilin Tong
2026-11-10 5:17 ` [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Andrew Morton
2 siblings, 0 replies; 5+ messages in thread
From: Weilin Tong @ 2026-11-05 9:52 UTC (permalink / raw)
To: catalin.marinas, akpm; +Cc: linux-mm, linux-kernel
Reading a kmemleak report walks all tracked objects under RCU, even
when the report is empty. On large debug kernels this can stall RCU.
Use kmemleak_cond_resched() in both seq traversal loops. Request a break
when need_resched() is set and periodically every 256 positions, since
preemption can clear need_resched() without ending the RCU read-side
critical section.
The helper pins a linked cursor and defers its removal across RCU breaks.
Already removed cursors remain under RCU to protect their forward links.
This allows RCU grace periods to progress during long report reads.
Fixes: f5886c7f96f2 ("kmemleak: Protect the seq start/next/stop sequence by rcu_read_lock()")
Assisted-by: LLM
Signed-off-by: Weilin Tong <tongweilin@linux.alibaba.com>
---
mm/kmemleak.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index d959d11f6..0fe7d336c 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -2216,6 +2216,9 @@ static void stop_scan_thread(void)
}
}
+/* Also break RCU periodically when preemption clears need_resched(). */
+#define KMEMLEAK_SEQ_RESCHED_INTERVAL 256
+
/*
* Iterate over the object_list and return the first valid object at or after
* the required position with its use_count incremented. The function triggers
@@ -2233,6 +2236,9 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos)
rcu_read_lock();
list_for_each_entry_rcu(object, &object_list, object_list) {
+ if (need_resched() || !(n % KMEMLEAK_SEQ_RESCHED_INTERVAL))
+ kmemleak_cond_resched(object);
+
if (n-- > 0)
continue;
if (get_object(object))
@@ -2256,6 +2262,9 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++(*pos);
list_for_each_entry_continue_rcu(obj, &object_list, object_list) {
+ if (need_resched() || !(*pos % KMEMLEAK_SEQ_RESCHED_INTERVAL))
+ kmemleak_cond_resched(obj);
+
if (get_object(obj)) {
next_obj = obj;
break;
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports
2026-11-05 9:52 [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Weilin Tong
2026-11-05 9:52 ` [PATCH 1/2] mm: kmemleak: serialize disable-time cleanup Weilin Tong
2026-11-05 9:52 ` [PATCH 2/2] mm: kmemleak: reschedule while reading reports Weilin Tong
@ 2026-11-10 5:17 ` Andrew Morton
2026-11-10 8:18 ` Weilin Tong
2 siblings, 1 reply; 5+ messages in thread
From: Andrew Morton @ 2026-11-10 5:17 UTC (permalink / raw)
To: Weilin Tong; +Cc: catalin.marinas, linux-mm, linux-kernel
On Thu, 5 Nov 2026 17:52:48 +0800 Weilin Tong <tongweilin@linux.alibaba.com> wrote:
> Reading a kmemleak report can traverse all tracked objects in one
> RCU read-side section and cause a stall.
>
> Serialize disable-time cleanup with clear operations and report readers,
> then use kmemleak_cond_resched() in both report traversal loops to let RCU
> progress safely during long reads.
Thanks. Has this been demonstrated? Are there real-world reports? Or
is this a theoretical thing from (LLM assisted) code inspection?
Please do share such details, they matter.
In [2/2], *pos does not advance while kmemleak_seq_next() skips objects
whose get_object() fails. If *pos isn't aligned to the 256 boundary
and preemption clears need_resched(), a long deleted chain gets no
periodic RCU break. Seems the code could tighten and simplify the "once
per 256 operations" logic?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports
2026-11-10 5:17 ` [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Andrew Morton
@ 2026-11-10 8:18 ` Weilin Tong
0 siblings, 0 replies; 5+ messages in thread
From: Weilin Tong @ 2026-11-10 8:18 UTC (permalink / raw)
To: Andrew Morton; +Cc: Weilin Tong, Catalin Marinas, linux-mm, linux-kernel
Hi Andrew,
Thanks for the review.
Yes, this was observed while reading /sys/kernel/debug/kmemleak on
our downstream distribution's 6.6-based debug kernel, without injected
delays. Here are excerpts from the original log:
[1023772.105996] rcu: INFO: rcu_preempt self-detected stall on CPU
[1023772.152485] rcu: (t=65047 jiffies g=357990333 q=711371 ncpus=96)
[1023772.491019] get_object+0x1e/0x70
[1023772.501186] kmemleak_seq_next+0x91/0xe0
[1023772.512982] seq_read_iter+0x482/0x1160
With CONFIG_HZ=1000, the grace period had lasted about 65 seconds.
I should have included this evidence in the cover letter.
You're right about *pos: it does not advance when get_object() fails,
so an unaligned position can miss the periodic checks throughout the
skip loop. Our deleted-chain tests checked safety, but missed this
progress issue.
I'll address this in v2, preserving safe traversal across concurrent
deletion, and add targeted coverage for this case.
Thanks,
Weilin
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-10 8:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-05 9:52 [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Weilin Tong
2026-11-05 9:52 ` [PATCH 1/2] mm: kmemleak: serialize disable-time cleanup Weilin Tong
2026-11-05 9:52 ` [PATCH 2/2] mm: kmemleak: reschedule while reading reports Weilin Tong
2026-11-10 5:17 ` [PATCH 0/2] mm: kmemleak: avoid long RCU read-side sections in reports Andrew Morton
2026-11-10 8:18 ` Weilin Tong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®