On 3/27/24 8:01 PM, Johannes Weiner wrote: > 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> Reviewed-by: Vlastimil Babka <vbabka@xxxxxxx> > --- > 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)