* [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
2026-11-05 9:52 ` [PATCH 2/2] mm: kmemleak: reschedule while reading reports Weilin Tong
0 siblings, 2 replies; 3+ 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] 3+ 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
1 sibling, 0 replies; 3+ 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] 3+ 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
1 sibling, 0 replies; 3+ 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] 3+ messages in thread
end of thread, other threads:[~2026-11-05 9:53 UTC | newest]
Thread overview: 3+ 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
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®