On Wed, Mar 27, 2024 at 09:54:01AM +0100, Vlastimil Babka wrote: > > @@ -1314,10 +1349,10 @@ static inline void expand(struct zone *zone, struct page *page, > > * Corresponding page table entries will not be touched, > > * pages will stay not present in virtual address space > > */ > > - if (set_page_guard(zone, &page[size], high, migratetype)) > > + if (set_page_guard(zone, &page[size], high)) > > continue; > > > > - add_to_free_list(&page[size], zone, high, migratetype); > > + add_to_free_list(&page[size], zone, high, migratetype, false); > > This is account_freepages() in the hot loop, what if we instead used > __add_to_free_list(), sum up nr_pages and called account_freepages() once > outside of the loop? How about this on top of the series? Could be folded into mm-page_alloc-consolidate-free-page-accounting, but for credit and bisectability (just in case) I think stand-alone makes sense. --- >From 361f5df28183d85c7718fe0b579438d3d58777be Mon Sep 17 00:00:00 2001 From: Johannes Weiner <hannes@xxxxxxxxxxx> Date: Wed, 27 Mar 2024 12:29:25 -0400 Subject: [PATCH 3/3] mm: page_alloc: batch vmstat updates in expand() expand() currently updates vmstat for every subpage. This is unnecessary, since they're all of the same zone and migratetype. Count added pages locally, then do a single vmstat update. Suggested-by: Vlastimil Babka <vbabka@xxxxxxx> Signed-off-by: Johannes Weiner <hannes@xxxxxxxxxxx> --- mm/page_alloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8987e8869f6d..13fe5c612fbe 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1341,6 +1341,7 @@ static inline void expand(struct zone *zone, struct page *page, int low, int high, int migratetype) { unsigned long size = 1 << high; + unsigned long nr_added = 0; while (high > low) { high--; @@ -1356,9 +1357,11 @@ static inline void expand(struct zone *zone, struct page *page, if (set_page_guard(zone, &page[size], high)) continue; - add_to_free_list(&page[size], zone, high, migratetype, false); + __add_to_free_list(&page[size], zone, high, migratetype, false); set_buddy_order(&page[size], high); + nr_added += size; } + account_freepages(zone, nr_added, migratetype); } static void check_new_page_bad(struct page *page) -- 2.44.0