[PATCH 1/2] mm: kmemleak: move the struct page scan into a helper
From: Breno Leitao
Date: Mon Sep 21 2026 - 09:13:33 EST
The struct page scanning loop sits inline in __kmemleak_scan(), nested
three levels deep and sharing the caller's "stop" variable with the
zone walk around it. Move it into scan_zone_pages(), which scans one
zone and returns 1 if scanning should stop.
No functional change; this only makes room for changing how the pages
are handed to scan_block().
Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
mm/kmemleak.c | 57 ++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 23 deletions(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 8fa409a4f9fb2..4040547a0af84 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1855,6 +1855,39 @@ static void dedup_flush(struct xarray *dedup)
}
}
+/*
+ * Scan the struct pages of a zone, skipping memory holes, pages that belong to
+ * another zone and pages that are not in use. Returns 1 if the scan should be
+ * stopped.
+ */
+static int scan_zone_pages(struct zone *zone)
+{
+ unsigned long start_pfn = zone->zone_start_pfn;
+ unsigned long end_pfn = zone_end_pfn(zone);
+ unsigned long pfn;
+
+ for (pfn = start_pfn; pfn < end_pfn; pfn++) {
+ struct page *page = pfn_to_online_page(pfn);
+
+ if (!(pfn & 63))
+ cond_resched_tasks_rcu_qs();
+
+ if (!page)
+ continue;
+
+ /* only scan pages belonging to this zone */
+ if (page_zone(page) != zone)
+ continue;
+ /* only scan if page is in use */
+ if (page_count(page) == 0)
+ continue;
+ if (scan_block(page, page + 1, NULL))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Scan data sections and all the referenced memory blocks allocated via the
* kernel's standard allocators. This function must be called with the
@@ -1928,29 +1961,7 @@ static int __kmemleak_scan(bool full)
*/
get_online_mems();
for_each_populated_zone(zone) {
- unsigned long start_pfn = zone->zone_start_pfn;
- unsigned long end_pfn = zone_end_pfn(zone);
- unsigned long pfn;
-
- for (pfn = start_pfn; pfn < end_pfn; pfn++) {
- struct page *page = pfn_to_online_page(pfn);
-
- if (!(pfn & 63))
- cond_resched_tasks_rcu_qs();
-
- if (!page)
- continue;
-
- /* only scan pages belonging to this zone */
- if (page_zone(page) != zone)
- continue;
- /* only scan if page is in use */
- if (page_count(page) == 0)
- continue;
- stop = scan_block(page, page + 1, NULL);
- if (stop)
- break;
- }
+ stop = scan_zone_pages(zone);
if (stop)
break;
}
--
2.53.0-Meta