[PATCH 1/4] mm: introduce for_each_free_list()
From: Brendan Jackman
Date: Wed May 13 2026 - 08:39:53 EST
There are a couple of places that iterate over the freelists with
awareness of the data structures' layout.
It seems ideally, code outside of mm should not be aware of the page
allocator's freelists at all. But, this patch just doesn't hide them
completely, it's just a meek incremental step in that direction: provide
a macro to iterate over it without needing to be aware of the actual
struct fields.
Signed-off-by: Brendan Jackman <jackmanb@xxxxxxxxxx>
---
include/linux/mmzone.h | 9 ++++++---
kernel/power/snapshot.c | 8 ++++----
mm/mm_init.c | 11 +++++++----
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 9adb2ad21da599354600b48b4f3f9a4158efa049..1331a7b93f33c67c6e07df1fd8c5e4504dc28e80 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -177,9 +177,12 @@ static inline bool migratetype_is_mergeable(int mt)
return mt < MIGRATE_PCPTYPES;
}
-#define for_each_migratetype_order(order, type) \
- for (order = 0; order < NR_PAGE_ORDERS; order++) \
- for (type = 0; type < MIGRATE_TYPES; type++)
+#define for_each_free_list(list, zone, order) \
+ for (order = 0; order < NR_PAGE_ORDERS; order++) \
+ for (unsigned int __type = 0; \
+ __type < MIGRATE_TYPES && \
+ (list = &(zone)->free_area[order].free_list[__type], 1); \
+ __type++)
extern int page_group_by_mobility_disabled;
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a564650734dcdceda7193ca3c1bc6b347cc1ec8b..d933b5b2c05d453bbda93c728136fc2a76758fc7 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1244,8 +1244,9 @@ unsigned int snapshot_additional_pages(struct zone *zone)
static void mark_free_pages(struct zone *zone)
{
unsigned long pfn, max_zone_pfn, page_count = WD_PAGE_COUNT;
+ struct list_head *free_list;
unsigned long flags;
- unsigned int order, t;
+ unsigned int order;
struct page *page;
if (zone_is_empty(zone))
@@ -1269,9 +1270,8 @@ static void mark_free_pages(struct zone *zone)
swsusp_unset_page_free(page);
}
- for_each_migratetype_order(order, t) {
- list_for_each_entry(page,
- &zone->free_area[order].free_list[t], buddy_list) {
+ for_each_free_list(free_list, zone, order) {
+ list_for_each_entry(page, free_list, buddy_list) {
unsigned long i;
pfn = page_to_pfn(page);
diff --git a/mm/mm_init.c b/mm/mm_init.c
index bd466a3c10c8e204dddd881c5334364e3d47d612..db5568cf36e12b6fe52854b274fc331d9b36cac3 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1429,11 +1429,14 @@ static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx,
static void __meminit zone_init_free_lists(struct zone *zone)
{
- unsigned int order, t;
- for_each_migratetype_order(order, t) {
- INIT_LIST_HEAD(&zone->free_area[order].free_list[t]);
+ struct list_head *list;
+ unsigned int order;
+
+ for_each_free_list(list, zone, order)
+ INIT_LIST_HEAD(list);
+
+ for (order = 0; order < NR_PAGE_ORDERS; order++)
zone->free_area[order].nr_free = 0;
- }
#ifdef CONFIG_UNACCEPTED_MEMORY
INIT_LIST_HEAD(&zone->unaccepted_pages);
--
2.51.2