diff options
| author | Ye Liu <ye.liu@linux.dev> | 2026-07-14 09:51:00 +0800 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-07-28 21:11:49 -0700 |
| commit | 53472eb262913d144df89ea959fcc30e43001f79 (patch) | |
| tree | c778c686cfa6ebebd760cc6958a265cd1e1727ba /include/linux | |
| parent | cdf95d6b3387b99a9377046491a0a51bad93b5af (diff) | |
mm/page_owner: extract skip_buddy_pages() helper to unify buddy page skipping
Patch series "mm/page_owner: misc cleanups", v6.
This series collects a few cleanups for mm/page_owner.c that have been
accumulated while reading through the file. There is no functional change
-- the goal is to make the code easier to read and maintain.
Patch 1 consolidates three identical PageBuddy skip blocks into a single
skip_buddy_pages() helper, eliminating the duplication and keeping the
lockless-read comment in one place.
Patch 2 replaces the -1 magic number used for "never migrated" with a
proper MR_NEVER member in enum migrate_reason, adds the corresponding
"never_migrated" string in the MIGRATE_REASON trace macro, and updates the
GDB page_owner script to use MR_NEVER so that lx-dump-page-owner correctly
detects unmigrated pages.
Patch 3 follows up by converting the remaining 'int reason' parameters
throughout the migration and hugetlb callchains to 'enum migrate_reason',
making the type explicit and gaining compiler checking. The 'short
last_migrate_reason' struct field in page_owner is intentionally left as
'short' since it is per-page metadata where size matters.
Patch 4 hoists the CONFIG_MEMCG guard out of print_page_owner_memcg()'s
body so that the real implementation and the empty stub are two clearly
separate definitions, the common kernel idiom.
Patch 5 adds a missing \n to the count_threshold debugfs attribute format
string so that cat(1) output is properly terminated.
Patch 6 moves free_ts_nsec from the allocation summary line to the free
section in __dump_page_owner(), grouping it with free_pid and free_tgid
where it logically belongs. This also makes the dump output consistent
with print_page_owner().
Patch 7 drops the redundant page_owner_ prefix from file-scoped static
symbols (stack_fops, threshold_fops, etc.). Since they cannot collide
across translation units, the prefix carries no information.
Patch 8 clamps the PFN advance in skip_buddy_pages() at the next
MAX_ORDER_NR_PAGES boundary. The lockless buddy_order_unsafe() read can
return a garbage order value if the page is concurrently allocated between
the PageBuddy check and the private read, potentially causing the PFN to
advance past the next bounadry whose pfn_valid() check would have caught
an offline memory section. In read_page_owner(), which relies solely on
boundary-aligned pfn_valid() to guard pfn_to_page(), this could lead to an
unmapped mem_section access.
Patch 9 avoids two TOCTOU issues in print_page_owner_memcg() by reusing
the page->memcg_data snapshot already taken via READ_ONCE at the top of
the function throughout, instead of calling page_memcg_check() and
PageMemcgKmem() which re-read page->memcg_data locklessly with VM_BUG_ON
assertions. If the page is concurrently freed and reallocated as a THP
tail or slab page between the initial guards and these later calls, those
assertions can fire on CONFIG_DEBUG_VM=y builds. The OBJEXTS (slab) case
is also simplified with an early return since objcg != memcg for slabs.
This patch (of 6):
Three places in page_owner.c duplicate the same pattern: check if a page
is PageBuddy, read its order via buddy_order_unsafe(), advance the pfn
past the buddy block if the order is valid, and continue.
Consolidate them into a single inline helper skip_buddy_pages(). The
function returns true (skip) for any buddy page and advances @pfn past the
block when the order is valid; returns false if the page is not a buddy
page and should be processed normally.
The old init_pages_in_zone() variant used "order > 0" as an extra guard
before advancing pfn, but the continue was unconditional and (1UL << 0) -
1 == 0, so the behaviour is identical. The comment about zone->lock is
preserved in the helper's kernel-doc.
No functional change.
Link: https://lore.kernel.org/20260714015117.78351-1-ye.liu@linux.dev
Link: https://lore.kernel.org/20260714015117.78351-2-ye.liu@linux.dev
Signed-off-by: Ye Liu <ye.liu@linux.dev>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'include/linux')
0 files changed, 0 insertions, 0 deletions
