Re: [PATCH v2 08/22] mm: introduce for_each_free_list()
From: Vlastimil Babka (SUSE)
Date: Mon May 11 2026 - 09:49:51 EST
On 3/20/26 19:23, Brendan Jackman wrote:
> Later patches will rearrange the free areas, but there are a couple of
> places that iterate over them with the assumption that they have the
> current structure.
>
> It seems ideally, code outside of mm should not be directly aware of
> struct free_area in the first place, but that awareness seems relatively
> harmless so just make the minimal change.
I think we should lift the code from kernel/power/snapshot.c to under mm/
eventually, ISTR discussing it somewhere recently. But doesn't have to be in
this series.
> Now instead of letting users manually iterate over the free lists, just
> provide a macro to do that. Then adopt that macro in a couple of places.
>
> Signed-off-by: Brendan Jackman <jackmanb@xxxxxxxxxx>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
> ---
> include/linux/mmzone.h | 7 +++++--
> kernel/power/snapshot.c | 8 ++++----
> mm/mm_init.c | 11 +++++++----
> 3 files changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 7bd0134c241ce..c49e3cdf4f6bb 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) \
> +#define for_each_free_list(list, zone, order) \
> for (order = 0; order < NR_PAGE_ORDERS; order++) \
> - for (type = 0; type < MIGRATE_TYPES; type++)
> + for (unsigned int type = 0; \
> + list = &zone->free_area[order].free_list[type], \
> + type < MIGRATE_TYPES; \
> + type++) \
>
> extern int page_group_by_mobility_disabled;
>
> diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
> index 7dcccf378cc2f..abd33ca13eec4 100644
> --- a/kernel/power/snapshot.c
> +++ b/kernel/power/snapshot.c
> @@ -1245,8 +1245,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))
> @@ -1270,9 +1271,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 969048f9b320c..f6f9455bc42b6 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -1445,11 +1445,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);
>