summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
10 daysmm/vmstat: avoid taking zone lock in /proc/buddyinfo readsImran Khan
frag_show_print() just reads zone->free_area[order].nr_free, so it can safely do this without needing the zone->lock. Pass nolock=true from frag_show(), so that walk_zones_in_node() can skip the zone->lock acquisition. Link: https://lore.kernel.org/20260604134245.1580287-1-imran.f.khan@oracle.com Signed-off-by: Imran Khan <imran.f.khan@oracle.com> Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Liam R. Howlett <liam@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/swap_state: remove unnecessary lru_add_drain() from readaheadUsama Arif
swap_cluster_readahead() and swap_vma_readahead() end the readahead loop with an explicit lru_add_drain() call. That drain is a leftover from 2.6.12 era code and serves no functional purpose for the callers: - do_swap_page() ignores LRU residency for the readahead folios; it only needs the target folio it called swapin_readahead() for, and if the write-fault path needs the target folio on the LRU to count references accurately, it runs its own lru_add_drain() at the wp_can_reuse_anon_folio() and do_swap_page() sites. - shmem_swapin_cluster() immediately locks the returned folio, waits for writeback, then operates on it - LRU residency of either the target or the readahead folios is irrelevant. - try_to_unuse() likewise locks the folio and calls unuse_pte() without depending on LRU presence. Folios newly added to the swap cache by the readahead loop sit in the per-CPU LRU folio_batch and will be drained naturally as the batch fills (FOLIO_BATCH_SIZE),by the next reclaim/compaction lru_add_drain_all() and so on. The unconditional drain only synchronously flushes a partial batch and forces contention on lruvec_lock. On a 176-CPU production host running a memory-pressured workload, this path was observed to call folio_batch_move_lru() from swap_cluster_readahead() ~28K/min, a very large source of LRU lock traffic. This is a direct continuation of the cleanup started in commit 1aa43598c03b ("mm: remove unnecessary calls to lru_add_drain") which removed the equivalent drain from free_pages_and_swap_cache() with the same rationale. A detailed reasoning for this is present in [1]. Remove both drains. Link: https://lore.kernel.org/20260608143242.2869392-1-usama.arif@linux.dev Link: https://lore.kernel.org/all/dca2824e8e88e826c6b260a831d79089b5b9c79d.camel@surriel.com/T/#u [1] Signed-off-by: Usama Arif <usama.arif@linux.dev> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Reviewed-by: Barry Song <baohua@kernel.org> Reviewed-by: Kairui Song <kasong@tencent.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Chris Li <chrisl@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Rik van Riel <riel@surriel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: constify oom_control, scan_control, and alloc_context nodemaskGregory Price
The nodemasks in these structures may come from a variety of sources, including tasks and cpusets - and should never be modified by any code when being passed around inside another context. Link: https://lore.kernel.org/20260609002919.3967782-1-gourry@gourry.net Signed-off-by: Gregory Price <gourry@gourry.net> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Barry Song <baohua@kernel.org> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Tested-by: SeongJae Park <sj@kernel.org> Acked-by: SeongJae Park <sj@kernel.org> Acked-by: Waiman Long <longman@redhat.com> Acked-by: Zi Yan <ziy@nvidia.com> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Brendan Jackman <jackmanb@google.com> Cc: Chris Li <chrisl@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Michal Koutný <mkoutny@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Tejun Heo <tj@kernel.org> Cc: Wei Xu <weixugc@google.com> Cc: Yuanchu Xie <yuanchu@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysinclude/linux/swap.h: remove unused leftoversRitesh Harjani (IBM)
This removed unused leftovers, most of them are forward structure declarations. Also removes SWAP_BATCH macro which isn't used any where in the code. Found these during manual code review. Link: https://lore.kernel.org/68591daf0d679e5a0072d63751f187d14613e2b0.1781146877.git.ritesh.list@gmail.com Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Reviewed-by: Barry Song <baohua@kernel.org> Acked-by: Chris Li <chrisl@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/damon/core: reduce kernel stack usageArnd Bergmann
The main thread function has recently grown to the point of exceeding stack frame size warning limits in some configurations. This is what I hit on s390 with clang and CONFIG_KASAN: mm/damon/core.c:3440:31: error: stack frame size (1352) exceeds limit (1280) in 'kdamond_fn' [-Werror,-Wframe-larger-than] 3440 | static int kdamond_fn(struct damon_ctx *ctx) The largest stack usage here is inside of the kdamond_tune_intervals(), so by marking that one as noinline_for_stack, the functions individually stay below the warning limit, though kdamond_fn() itself still uses hundreds of kilobytes for some reason. Link: https://lore.kernel.org/20260611125704.3386176-1-arnd@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: SeongJae Park <sj@kernel.org> Cc: Bill Wendling <morbo@google.com> Cc: Justin Stitt <justinstitt@google.com> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Quanmin Yan <yanquanmin1@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: move alloc tag to mmLorenzo Stoakes
The alloc tagging work is really mm-specific, so move alloc_tag.c to mm/ and additionally update the MAINTAINERS entry to place it within memory management and port over the Kconfig and Makefile code to mm. Link: https://lore.kernel.org/20260625184857.2193482-3-surenb@google.com Signed-off-by: Lorenzo Stoakes <ljs@kernel.org> Signed-off-by: Suren Baghdasaryan <surenb@google.com> Reviewed-by: SeongJae Park <sj@kernel.org> Tested-by: Hao Ge <hao.ge@linux.dev> Acked-by: Hao Ge <hao.ge@linux.dev> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Harry Yoo (Oracle) <harry@kernel.org> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Cc: Brendan Jackman <jackmanb@google.com> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Liam R. Howlett <liam@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysMAINTAINERS: move inactive maintainer to CREDITSSuren Baghdasaryan
Patch series "move alloc_tag.c file under mm/". Memory allocation profiling is ultimately an mm feature and now that we need to use some internal mm definitions in it [1], the time is right to move its implementation under mm/. The move is straight-forward, involving just alloc_tag.c file. Update config, makefiles and maintainers as well. This patch (of 2): Move Kent Overstreet from maintainers for Memory Allocation Profiling to CREDITS in recognition of his co-authorship and contributions to this feature. Link: https://lore.kernel.org/20260625184857.2193482-2-surenb@google.com Link: https://lore.kernel.org/all/20260622-alloc-trylock-v2-13-31f31367d420@google.com/ [1] Signed-off-by: Suren Baghdasaryan <surenb@google.com> Acked-by: Lorenzo Stoakes <ljs@kernel.org> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Brendan Jackman <jackmanb@google.com> Cc: David Hildenbrand <david@kernel.org> Cc: Liam R. Howlett <liam@infradead.org> Cc: Mike Rapoport <rppt@kernel.org> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Hao Ge <hao.ge@linux.dev> Cc: Harry Yoo (Oracle) <harry@kernel.org> Cc: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/zsmalloc: document free_zspage helper variantsWenchao Hao
After splitting __free_zspage() into a lockless core and a wrapper that does the class-stat bookkeeping, three similarly-named helpers coexist: free_zspage / __free_zspage / __free_zspage_lockless. Add a comment block above them describing what each does and where it is used, so the names are not easy to confuse. No functional change. Link: https://lore.kernel.org/20260626015003.2965881-5-haowenchao22@gmail.com Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com> Suggested-by: Nhat Pham <nphamcs@gmail.com> Reviewed-by: Nhat Pham <nphamcs@gmail.com> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Cc: Xueyuan Chen <xueyuan.chen21@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/zsmalloc: drop class lock before freeing zspageXueyuan Chen
Currently in zs_free(), the class->lock is held until the zspage is completely freed and the counters are updated. However, freeing pages back to the buddy allocator requires acquiring the zone lock. Under heavy memory pressure, zone lock contention can be severe. When this happens, the CPU holding the class->lock will stall waiting for the zone lock, thereby blocking all other CPUs attempting to acquire the same class->lock. This patch shrinks the critical section of the class->lock to reduce lock contention. By moving the actual page freeing process outside the class->lock, we can improve the concurrency performance of zs_free(). Testing on the RADXA O6 platform shows that with 12 CPUs concurrently performing zs_free() operations, the execution time is reduced by 20%. Link: https://lore.kernel.org/20260626015003.2965881-4-haowenchao22@gmail.com Signed-off-by: Xueyuan Chen <xueyuan.chen21@gmail.com> Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com> Reviewed-by: Nhat Pham <nphamcs@gmail.com> Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Minchan Kim <minchan@kernel.org> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/zsmalloc: drop pool->lock from zs_free on 64-bit systemsWenchao Hao
With class_idx encoded in obj, zs_free() can locate the size_class without holding pool->lock on 64-bit systems. Page migration also takes class->lock and only rewrites the PFN field of obj, so: 1. read obj locklessly, 2. lock the size_class derived from obj's class_idx, 3. re-read obj under class->lock to get a stable PFN. This eliminates the rwlock read-side cacheline bouncing between zs_free() and migration/compaction on multi-core systems. Annotate handle_to_obj()/record_obj() with READ_ONCE()/WRITE_ONCE() to prevent load/store tearing on the lockless read path and silence KCSAN data race reports. When ZS_OBJ_CLASS_BITS == 0 (32-bit, or 64-bit with obj too narrow to hold class_idx), zs_free() keeps pool->lock. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix obj_to_class_idx() warning yet again] [baohua@kernel.org: update the comment about pool lock] Link: https://lore.kernel.org/20260725035733.53241-1-baohua@kernel.org Link: https://lore.kernel.org/20260626015003.2965881-3-haowenchao22@gmail.com Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com> Reviewed-by: Nhat Pham <nphamcs@gmail.com> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Cc: Xueyuan Chen <xueyuan.chen21@gmail.com> Cc: kernel test robot <lkp@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/zsmalloc: encode class index in obj value for lockless class lookupWenchao Hao
Patch series "mm/zsmalloc: reduce lock contention in zs_free()", v6. This series reduces lock contention in zs_free(), which dominates the unmap path under memory pressure on Android (LMK kills) and on x86 servers running zswap-heavy workloads. The current zs_free() takes pool->lock (rwlock, read side) just to look up the size_class for a handle, then takes class->lock and holds it across __free_zspage() which can call into the buddy allocator and acquire zone->lock. Two costs follow: * pool->lock reader-counter cacheline bouncing among concurrent zs_free() callers. * class->lock held across folio_put(), so any zone->lock wait fans out to every other zs_free() on the same class. The series tackles both: Patch 1: encode size_class index into obj alongside PFN and obj_idx, so zs_free() can locate the class without pool->lock. Patch 2: drop pool->lock from zs_free() on 64-bit; 32-bit unchanged. Patch 3: move zspage page-freeing out of class->lock. Patch 4: document the three free_zspage helper variants that result from the split in patch 3. Performance results: Test: each process independently mmap 256MB, write data, madvise MADV_PAGEOUT to swap out via zram (lzo-rle), then concurrent munmap. Raspberry Pi 4B (4-core ARM64 Cortex-A72): mode Base Patched Speedup single 59.0ms 56.0ms 1.05x multi 2p 94.6ms 66.7ms 1.42x multi 4p 202.9ms 110.6ms 1.83x x86 (20-core Intel i7-12700, 16 concurrent processes): mode Base Patched Speedup single 11.7ms 9.8ms 1.19x multi 2p 24.1ms 17.2ms 1.40x multi 4p 63.0ms 45.3ms 1.39x This patch (of 4): Encode the size_class index (class_idx) into the obj value so that zs_free() can determine the correct size_class without dereferencing the handle->obj->PFN->zpdesc->zspage->class chain under pool->lock. class_idx is invariant across page migration (only PFN is rewritten), so a lockless read of obj always yields a valid class_idx. Where obj has more bits below the PFN field than obj_idx alone needs, split that space into class_idx and obj_idx subfields: |<-- _PFN_BITS -->|<-- ZS_OBJ_CLASS_BITS -->|<-- ZS_OBJ_IDX_BITS -->| +-----------------+-------------------------+-----------------------+ | PFN | class_idx | obj_idx | +-----------------+-------------------------+-----------------------+ MSB ^ LSB | +-- ZS_OBJ_PFN_SHIFT The macro layout changes as follows: Before After Meaning ---------------- ------------------ ---------------------------- OBJ_INDEX_BITS ZS_OBJ_IDX_BITS width of obj_idx subfield OBJ_INDEX_MASK ZS_OBJ_IDX_MASK mask of obj_idx subfield (n/a) ZS_OBJ_CLASS_BITS width of class_idx subfield (n/a) ZS_OBJ_CLASS_MASK mask of class_idx subfield (n/a) ZS_OBJ_PFN_SHIFT bit offset of PFN in obj ZS_OBJ_CLASS_BITS folds to 0 (and the layout collapses to [PFN | obj_idx]) when obj has no spare bits, i.e. on 32-bit or on 64-bit fallback paths where MAX_POSSIBLE_PHYSMEM_BITS == BITS_PER_LONG (e.g. UML); zs_free() then falls back to pool->lock. [akpm@linux-foundation.org: fix obj_to_class_idx() defined but not used, remove duplicated #ifdef] Link: https://lore.kernel.org/20260626015003.2965881-1-haowenchao22@gmail.com Link: https://lore.kernel.org/20260626015003.2965881-2-haowenchao22@gmail.com Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com> Reviewed-by: Nhat Pham <nphamcs@gmail.com> Cc: Barry Song <baohua@kernel.org> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Sergey Senozhatsky <senozhatsky@chromium.org> Cc: Xueyuan Chen <xueyuan.chen21@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: annotate data-race in cpu_needs_drain()Xuewen Wang
KCSAN reports a data-race when cpu_needs_drain() reads another CPU's per-cpu folio_batch->nr without locking, while the owning CPU writes to it via folio_batch_add(). Reading a slightly stale value is harmless -- cpu_needs_drain() only decides whether to schedule a drain, and the next iteration of __lru_add_drain_all() will re-check. Use data_race() to annotate the intentional race. [akpm@linux-foundation.org: reindent cpu_needs_drain, per David & Lorenzo] Link: https://lore.kernel.org/20260626053700.2036899-1-wangxuewen@kylinos.cn Signed-off-by: Xuewen Wang <wangxuewen@kylinos.cn> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Barry Song <baohua@kernel.org> Cc: Chris Li <chrisl@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Wei Xu <weixugc@google.com> Cc: Yuanchu Xie <yuanchu@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysradix-tree: add/correct some kernel-docRandy Dunlap
Correct some kernel-doc issues in radix-tree.h: - use "DOC:" so that a kernel-doc comment is parsed correctly (or we could just use "/*" for that comment) - add one function parameter description - add one function parameter name inside the prototype to fix these warnings: Warning: include/linux/radix-tree.h:164 Incorrect use of kernel-doc format: * radix_tree_deref_slot - dereference a slot Warning: include/linux/radix-tree.h:177 cannot understand function prototype: '* @slot: slot pointer, returned by radix_tree_lookup_slot Warning: include/linux/radix-tree.h:192 function parameter 'treelock' not described in 'radix_tree_deref_slot_protected' Warning: include/linux/radix-tree.h:309 function parameter '' not described in 'radix_tree_next_chunk' Link: https://lore.kernel.org/20260627185859.1632928-1-rdunlap@infradead.org Signed-off-by: Randy Dunlap <rdunlap@infradead.org> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daystmpfs: zero unused folio tail for long symlinksYousef Alhouseen
shmem_symlink() marks the entire folio uptodate after copying only the NUL-terminated link target. The remainder of the freshly allocated folio is left uninitialized. Reclaim may pass the whole folio to a swap compressor. KMSAN observed sw842_compress() computing a checksum over the uninitialized tail. If the folio is written to a swap device, those bytes can also leave the kernel. Zero the remainder of the folio before marking it uptodate and dirty. Link: https://lore.kernel.org/20260628004314.27370-1-alhouseenyousef@gmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+bf5586280a66e9ccdfa9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=bf5586280a66e9ccdfa9 Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/kmemleak: skip the remaining scan phases when interruptedBreno Leitao
kmemleak_scan() scans the per-cpu sections, the struct page ranges and the task stacks in sequence. Each loop now bails out once scan_block() reports the scan was interrupted, but the later phases are still entered and only bail on their first scan_block() call. Jump straight to the gray list scan once a phase reports an interrupted scan, so the remaining scan phases are not entered at all. This does not change the scan results, it only avoids the pointless re-entry. Link: https://lore.kernel.org/20260626-kmemleak_improve-v1-1-d40c7616f64f@debian.org Signed-off-by: Breno Leitao <leitao@debian.org> Suggested-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/mm_init: fold __init_page_from_nid() into __init_deferred_page()Muchun Song
__init_page_from_nid() no longer has external users and is only used locally in mm/mm_init.c under CONFIG_DEFERRED_STRUCT_PAGE_INIT. Fold it into its sole caller __init_deferred_page() and remove the separate helper declaration. Link: https://lore.kernel.org/20260612035903.2468601-20-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: remove unused bootmem cma fieldMuchun Song
struct huge_bootmem_page no longer needs to keep the CMA pointer. The bootmem path only needs to remember whether a huge page came from CMA, which is already encoded in the flags field. Set HUGE_BOOTMEM_CMA when the page is allocated, drop the unused cma field together with the redundant assignments, and simplify the early CMA bootmem allocation fallback path now that the cma pointer no longer has to be stored in struct huge_bootmem_page. Link: https://lore.kernel.org/20260612035903.2468601-19-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/sparse-vmemmap: remove sparse_vmemmap_init_nid_late()Muchun Song
hugetlb_vmemmap_init_late() no longer has any users, so the remaining late-init path in sparse_vmemmap_init_nid_late() is dead code. Remove sparse_vmemmap_init_nid_late() and its declarations. Link: https://lore.kernel.org/20260612035903.2468601-18-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: remove obsolete bootmem cross-zone checksMuchun Song
Bootmem gigantic HugeTLB pages used to be validated again during gather_bootmem_prealloc_node() and any cross-zone pages were discarded there. That validation is no longer needed. Cross-zone bootmem gigantic pages are now detected during allocation and freed before they reach the later bootmem gathering path, so the remaining pages are already zone-valid. Remove the obsolete cross-zone validation, invalid-page freeing, and the associated discarded-page accounting. Link: https://lore.kernel.org/20260612035903.2468601-17-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb_vmemmap: move bootmem HVO setup to early initMuchun Song
Bootmem HugeTLB pages currently defer HVO setup to hugetlb_vmemmap_init_late(), because the optimization needs zone information. Now that zone initialization is available earlier, the bootmem HVO setup can be done directly from hugetlb_vmemmap_init_early(). This lets gigantic HugeTLB pages apply HVO as soon as they are allocated. Bootmem gigantic pages that span multiple zones are now filtered out when they are allocated, so the remaining bootmem gigantic pages seen by later hugetlb initialization are already zone-valid. As a result, hugetlb_vmemmap_init_late() no longer needs to handle bootmem HVO setup. Link: https://lore.kernel.org/20260612035903.2468601-16-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Usama Arif <usama.arif@linux.dev> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: free cross-zone bootmem gigantic pages after allocationMuchun Song
Now that hugetlb reservation runs after zone initialization, bootmem gigantic page allocation can detect pages that span multiple zones. Keep those cross-zone pages separate during allocation and free them after allocation completes, so later hugetlb initialization only sees zone-valid gigantic pages. This chooses to free cross-zone gigantic pages directly instead of retrying allocation. In practice, such cross-zone cases are expected to be very rare, so adding retry logic does not seem justified at this point. Keeping the handling simple also preserves the previous behavior. If similar real-world reports show up later, retry support can be reconsidered then. Link: https://lore.kernel.org/20260612035903.2468601-15-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: refactor early boot gigantic hugepage allocationMuchun Song
The early boot gigantic hugepage allocation helpers currently mix allocation with huge_bootmem_page setup, and leave part of the initialization flow in architecture code. Refactor the interface to return the allocated huge page pointer and move the huge_bootmem_page setup into the generic hugetlb code. This makes the architecture-specific paths focus only on finding memory, while the common code handles node placement and early page metadata setup in one place. This also lets powerpc benefit from memblock_reserved_mark_noinit(), which it did not enable before. In addition, upcoming cross-zone validation for boot-time gigantic hugetlb reservation is common logic. With this refactoring, that logic can stay in the generic code instead of being duplicated in architecture-specific paths. Link: https://lore.kernel.org/20260612035903.2468601-14-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb_cma: validate hugetlb CMA range by zone at reserve timeMuchun Song
Hugetlb CMA allocation currently has to cope with CMA areas that span multiple zones. Validate the reserved CMA range up front in hugetlb_cma_reserve() so later hugetlb CMA allocations can assume a zone-consistent area. Also drop the pfn_valid() check from cma_validate_zones(). mem_section is not fully initialized at this point, so the check can trigger false warnings. Keep the sanity check in cma_activate_area() instead. Link: https://lore.kernel.org/20260612035903.2468601-13-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/sparse: move sparse_vmemmap_init_nid_late() into sparse_init_nid()Muchun Song
sparse_vmemmap_init_nid_late() is still called separately from mm_core_init_early(), away from the rest of the sparse initialization path. Now that sparse_init() runs after zone initialization, call sparse_vmemmap_init_nid_late() from sparse_init_nid() instead. This keeps both sparse_vmemmap_init_nid_early() and sparse_vmemmap_init_nid_late() in the sparse setup path. Link: https://lore.kernel.org/20260612035903.2468601-12-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/mm_init: remove set_pageblock_order() call from sparse_init()Muchun Song
free_area_init() already sets pageblock_order before sparse_init() runs for CONFIG_HUGETLB_PAGE_SIZE_VARIABLE, so sparse_init() does not need to call set_pageblock_order() again. With that call removed, set_pageblock_order() is only used in mm/mm_init.c. Make it static. Link: https://lore.kernel.org/20260612035903.2468601-11-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/mm_init: defer hugetlb reservation until after zone initializationMuchun Song
hugetlb_cma_reserve() and hugetlb_bootmem_alloc() currently run before free_area_init(), so HugeTLB reservation happens before zone state is initialized. Move the reservation step after free_area_init() so the relevant zone information is available before HugeTLB reserves memory. This is needed for later hugetlb changes that validate boot-time HugeTLB reservations against zone boundaries. Link: https://lore.kernel.org/20260612035903.2468601-10-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/mm_init: defer sparse_init() until after zone initializationMuchun Song
free_area_init() is responsible for initializing pgdat and zone state. Calling sparse_init() from there mixes in later vmemmap and struct page setup, which makes the initialization flow less clear. Defer sparse_init(), sparse_vmemmap_init_nid_late(), and memmap_init() until after free_area_init() completes, when zone initialization is fully done. This keeps free_area_init() focused on zone setup and ensures that sparse_init() runs with the relevant zone state already available. This is also a prerequisite for later hugetlb vmemmap changes that need zone information during early sparse vmemmap setup. Link: https://lore.kernel.org/20260612035903.2468601-9-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/sparse: move subsection_map_init() into sparse_init()Muchun Song
subsection_map_init() is part of sparse memory initialization, but it is currently called from free_area_init(). Move it into sparse_init() so the sparse-specific setup stays together instead of being split across the generic free_area_init() path. Link: https://lore.kernel.org/20260612035903.2468601-8-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Oscar Salvador <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/sparse: panic on memmap and usemap allocation failureMuchun Song
When vmemmap or usemap allocation fails, sparse_init_nid() currently marks the section non-present and continues. Later boot-time code can still walk PFNs in that section without checking for this partial setup, which leads to invalid accesses. subsection_map_init() can also touch an unallocated usemap. Auditing and fixing all early PFN walkers for this case is not worth the complexity. These allocation failures are expected to be fatal anyway, and other memory models already treat them that way. Make memmap and usemap allocation failures panic immediately instead of trying to recover and crashing later in less obvious ways. This is also consistent with how other memory model configurations handle memmap allocation failures. Link: https://lore.kernel.org/20260612035903.2468601-7-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Oscar Salvador <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/mm_init: simplify deferred_free_pages() migratetype initMuchun Song
deferred_free_pages() open-codes two loops to initialize the pageblock migratetype for a range of pages. Replace them with pageblock_migratetype_init_range() to remove the duplication and make the code clearer (Note that deferred_free_pages() may be called from atomic context). Link: https://lore.kernel.org/20260612035903.2468601-6-songmuchun@bytedance.com Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Oscar Salvador <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: initialize gigantic bootmem hugepage struct pages earlierMuchun Song
Gigantic bootmem HugeTLB pages are currently initialized from hugetlb_init(), but page_alloc_init_late() runs earlier and walks pageblocks to determine zone contiguity. If a bootmem HugeTLB region is marked noinit, set_zone_contiguous() can observe still-uninitialized struct pages through __pageblock_pfn_to_page(). This may not trigger an immediate failure, but it can make set_zone_contiguous() compute the wrong zone contiguity state. If extra poisoned-page checks are added in this path, such as PF_POISONED_CHECK() in page_zone_id(), it can also trigger an early boot panic. Initialize gigantic bootmem HugeTLB struct pages from page_alloc_init_late(), before zone contiguity is evaluated, so later page allocator setup only sees valid struct page state. This also makes the initialization order more natural, as struct pages should be initialized before later code inspects them. Link: https://lore.kernel.org/20260612035903.2468601-5-songmuchun@bytedance.com Fixes: fde1c4ecf916 ("mm: hugetlb: skip initialization of gigantic tail struct pages if freed by HVO") Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Oscar Salvador <osalvador@suse.de> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 dayspowerpc/mm: fix wrong addr_pfn tracking in compound vmemmap populationMuchun Song
vmemmap_populate_compound_pages() uses addr_pfn to determine the PFN offset within a compound page and to decide whether the current vmemmap slot should be populated as a head page mapping or should reuse a tail page mapping. However, addr_pfn is advanced manually in parallel with addr. The loop itself progresses in vmemmap address space, so each PAGE_SIZE step in addr covers PAGE_SIZE / sizeof(struct page) struct page slots. Since addr_pfn is compared against nr_pages in data-PFN units, it should advance by the same number of PFNs. The existing manual increments do not match that and therefore do not reliably track the PFN corresponding to the current addr. As a result, pfn_offset can be computed from the wrong PFN and the code can make the head/tail decision for the wrong compound-page position. Fix this by deriving addr_pfn directly from the current vmemmap address instead of carrying it as loop state. Link: https://lore.kernel.org/20260612035903.2468601-4-songmuchun@bytedance.com Fixes: f2b79c0d7968 ("powerpc/book3s64/radix: add support for vmemmap optimization for radix") Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Oscar Salvador <osalvador@suse.de> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb_vmemmap: fix __hugetlb_vmemmap_optimize_folios()Muchun Song
__hugetlb_vmemmap_optimize_folios() uses incorrect arguments when handling bootmem HugeTLB folios. The section number passed to register_page_bootmem_memmap() is derived from the vmemmap virtual address of folio->page instead of the folio PFN, so the bootmem memmap metadata can be registered against the wrong section. The helper is also given HUGETLB_VMEMMAP_RESERVE_SIZE even though it expects a page count, not a size in bytes. In addition, the write-protect range is based on pages_per_huge_page(h), which does not cover the full HugeTLB vmemmap area and can leave part of the shared tail vmemmap mapping writable. Fix the section lookup to use folio_pfn(folio), use HUGETLB_VMEMMAP_RESERVE_PAGES when registering the reserved memmap pages, and use hugetlb_vmemmap_size(h) for the write-protect range. Link: https://lore.kernel.org/20260612035903.2468601-3-songmuchun@bytedance.com Fixes: 752fe17af693 ("mm/hugetlb: add pre-HVO framework") Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Oscar Salvador <osalvador@suse.de> Reviewed-by: Frank van der Linden <fvdl@google.com> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Usama Arif <usama.arif@linux.dev> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/hugetlb: fix boot panic with CONFIG_DEBUG_VM and HVO bootmem pagesMuchun Song
Patch series "mm: Refactor bootmem gigantic hugepage allocation", v4. This series is split out from the earlier larger series "mm: Generalize HVO for HugeTLB and device DAX" [1]. It collects the first 19 patches of that series as a standalone set of fixes and preparatory cleanups around bootmem HugeTLB handling, sparse initialization ordering, and related vmemmap setup. The first patches fix a few bugs found while reviewing the existing code, including incorrect bootmem HVO handling, wrong vmemmap registration arguments, a powerpc compound-vmemmap tracking bug, and too-late initialization of gigantic bootmem HugeTLB struct pages. The rest of the series reorders early memory initialization so the relevant zone state is available before sparse and HugeTLB boot-time setup runs, then simplifies the remaining bootmem gigantic hugepage allocation path and removes code made obsolete by that rework. At a high level: - patches [1-4] fix boot-time and arch-specific bugs - patches [5-12] reorder and simplify sparse/mm/hugetlb early init - patches [13-19] refactor bootmem gigantic hugepage allocation and remove obsolete helpers and state This patch (of 19): Commit 622026e87c40 ("mm/hugetlb: remove fake head pages") switched HVO to reuse per-zone shared tail pages from zone->vmemmap_tails[]. Those shared tail pages were initialized in hugetlb_vmemmap_init(), but bootmem HugeTLB folios are prepared earlier from gather_bootmem_prealloc(). With hugetlb_free_vmemmap=on, prep_and_add_bootmem_folios() can access pageblock flags on bootmem HugeTLB pages whose mirrored tail struct pages already point to the shared tail page. On CONFIG_DEBUG_VM kernels, get_pfnblock_bitmap_bitidx() then dereferences the still-uninitialized shared tail page and can panic during boot. Initialize zone->vmemmap_tails[] from gather_bootmem_prealloc(), before bootmem HugeTLB folios are processed, and drop the later initialization from hugetlb_vmemmap_init(). This bug only affects CONFIG_DEBUG_VM kernels, where the relevant assertion is evaluated. Link: https://lore.kernel.org/20260612035903.2468601-1-songmuchun@bytedance.com Link: https://lore.kernel.org/20260612035903.2468601-2-songmuchun@bytedance.com Fixes: 622026e87c40 ("mm/hugetlb: remove fake head pages") Signed-off-by: Muchun Song <songmuchun@bytedance.com> Acked-by: Oscar Salvador <osalvador@suse.de> Tested-by: Michal Clapinski <mclapinski@google.com> Reviewed-by: Michal Clapinski <mclapinski@google.com> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Mike Rapoport <rppt@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Frank van der Linden <fvdl@google.com> Cc: Oscar Salvador (SUSE) <osalvador@kernel.org> Cc: Usama Arif <usama.arif@linux.dev> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 dayspercpu_ref: fix documentation of maximum valueMatthew Wilcox (Oracle)
Tejun changd percpu_ref to use long instead of int back in 2014 but missed updating this bit of the documentation. Also add the documentation to the htmldocs. Link: https://lore.kernel.org/20241211204017.184512-1-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/page_alloc: drop flag-conversion "optimisation"Brendan Jackman
This code uses flag equivalences to try to optimise conversion from GFP_ to ALLOC_ but there's no clear reason to believe it makes things faster. Even if it gets rid of conditional branches, it just trades them for a data dependency. CPUs are pretty good at conditional branches. But, in my GCC x86 build it doesn't look like there are any branches anyway, the compiler found some conditional instruction tricks. (Caveat: This was extracted & annotated by Gemini AI, I did not actually read the disasm myself) Old code: ae50: 8b 04 24 mov (%rsp),%eax # Load gfp_mask ... ae5d: 41 89 c4 mov %eax,%r12d ae64: 41 81 e4 20 08 00 00 and $0x820,%r12d # Mask both flags at once ... ae6f: 44 89 e1 mov %r12d,%ecx ae77: 83 c9 40 or $0x40,%ecx # OR with ALLOC_CPUSET (0x40) ae7a: 89 4c 24 60 mov %ecx,0x60(%rsp) # Store to alloc_flags New code: For __GFP_HIGH ( 0x20 ): It uses the Carry Flag (via sbb ) to conditionally add 0x20 to the base 0x40 ( ALLOC_CPUSET ) flag: ae63: 83 e0 20 and $0x20,%eax # Test __GFP_HIGH ... ae6a: 83 f8 01 cmp $0x1,%eax # Set carry flag if 0 ae6f: 45 19 e4 sbb %r12d,%r12d # %r12d = (gfp & 0x20) ? 0 : -1 ae80: 41 83 e4 e0 and $0xffffffe0,%r12d # %r12d = (gfp & 0x20) ? 0 : -32 ae87: 41 83 c4 60 add $0x60,%r12d # %r12d = (gfp & 0x20) ? 0x60 : 0x40 For __GFP_KSWAPD_RECLAIM ( 0x800 ): It uses a conditional move ( cmov ) later in the function to set the ALLOC_KSWAPD ( 0x800 ) bit: ae72: 25 00 08 00 00 and $0x800,%eax # Test __GFP_KSWAPD_RECLAIM ae77: 89 44 24 30 mov %eax,0x30(%rsp) # Store result ... af2c: 80 cf 08 or $0x8,%bh # Set ALLOC_KSWAPD (0x800) in temp reg af2f: 45 85 c9 test %r9d,%r9d # Check if __GFP_KSWAPD_RECLAIM was set af32: 0f 44 d8 cmove %eax,%ebx # If not, revert to flags without it Testing with a modified version[0] of lib/free_pages_test.c (adding printks with timing)... Old results from a Sapphire Rapids consumer CPU: [ 67.157118] page_alloc_test: Testing with GFP_KERNEL [ 67.157122] page_alloc_test: Starting 1,000,000 allocations... [ 70.704446] page_alloc_test: Completed. Time: 3543002 us (Avg: 3543.00 ns per alloc+free loop) [ 70.704456] page_alloc_test: Testing with GFP_KERNEL | __GFP_COMP [ 70.704460] page_alloc_test: Starting 1,000,000 allocations... [ 70.944672] page_alloc_test: Completed. Time: 239980 us (Avg: 239.98 ns per alloc+free loop) [ 70.944675] page_alloc_test: Test completed New results: [ 70.079015] page_alloc_test: Testing with GFP_KERNEL [ 70.079020] page_alloc_test: Starting 1,000,000 allocations... [ 73.669396] page_alloc_test: Completed. Time: 3586954 us (Avg: 3586.95 ns per alloc+free loop) [ 73.669402] page_alloc_test: Testing with GFP_KERNEL | __GFP_COMP [ 73.669405] page_alloc_test: Starting 1,000,000 allocations... [ 73.905084] page_alloc_test: Completed. Time: 235496 us (Avg: 235.49 ns per alloc+free loop) [ 73.905086] page_alloc_test: Test completed Seems like a wash. So, drop the flag value coupling here and let the compiler and CPU do their job. Superscalar CPUs are pretty neat after all. (Used AI for the disasm but the rest is all manual). Link: https://lore.kernel.org/20260629-gfp-pessimisation-v2-1-311ece6a8637@google.com Link: https://lore.kernel.org/20260615-gfp-pessimisation-v2-1-65f1319e6818@google.com Link: https://github.com/bjackman/aethelred/blob/2ccdc84ef087c2a631914f58e106e99e19bd3b98/page-alloc-test/page-alloc-test.c [1] Signed-off-by: Brendan Jackman <jackmanb@google.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Reviewed-by: Gregory Price <gourry@gourry.net> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Harry Yoo (Oracle) <harry@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 dayswriteback.h: fix a typo in the wbc_init_bio() descriptionAndreas Gruenbacher
initializtion -> initialization (missing "a") Link: https://lore.kernel.org/20260615162244.2170866-2-willy@infradead.org Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: add writeback.h to docs buildMatthew Wilcox (Oracle)
There's four functions in this header file with kernel-doc; add them to the htmldocs. Link: https://lore.kernel.org/20260615162244.2170866-1-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/page_owner: document page_owner filterZhen Ni
Add documentation for the page_owner_filter userspace tool and kernel-level filtering features. [rdunlap@infradead.org: avoid docs build warning] Link: https://lore.kernel.org/20260708213548.469155-1-rdunlap@infradead.org Link: https://lore.kernel.org/20260707115411.1714314-5-zhen.ni@easystack.cn Signed-off-by: Zhen Ni <zhen.ni@easystack.cn> Signed-off-by: Randy Dunlap <rdunlap@infradead.org> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Acked-by: Zi Yan <ziy@nvidia.com> Cc: Brendan Jackman <jackmanb@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daystools/mm: add page_owner_filter userspace toolZhen Ni
Add a userspace filtering tool for page_owner that supports per-fd filtering with print_mode and NUMA node filters. Features: - Three print modes: stack (default), handle, stack_handle - NUMA node filtering with flexible formats (single: 0, multiple: 0,1,2, range: 0-3, mixed: 0,2-3) - Per-file-descriptor filter state for independent filtering Usage examples: # Filter by print mode ./page_owner_filter -m handle ./page_owner_filter -m stack_handle # Filter by NUMA node ./page_owner_filter -n 0 ./page_owner_filter -n 0-3 # Combined filters ./page_owner_filter -m stack -n 0,1,2 ./page_owner_filter -m handle -n 0,2-3 The tool validates inputs before sending commands to the kernel and provides clear error messages when the kernel does not support per-fd filtering. Link: https://lore.kernel.org/20260707115411.1714314-4-zhen.ni@easystack.cn Signed-off-by: Zhen Ni <zhen.ni@easystack.cn> Tested-by: Zi Yan <ziy@nvidia.com> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Acked-by: Zi Yan <ziy@nvidia.com> Cc: Brendan Jackman <jackmanb@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/page_owner: add NUMA node filterZhen Ni
Add NUMA node filtering functionality to page_owner to allow filtering pages by specific NUMA node(s). This is useful for NUMA-aware memory allocation analysis and debugging. The filter supports flexible input formats: - Single node: nid=0 - Multiple nodes: nid=0,2,3 - Node range: nid=0-3 - Mixed format: nid=0,2-4,7 Example usage: # Using the page_owner_filter tool (recommended) ./page_owner_filter -n 0-3 ./page_owner_filter -m stack_handle -n 0,2-4,7 The implementation uses per-file-descriptor filter state stored in file->private_data, allowing each opener to have independent filter configuration. It uses nodemask_t for efficient multi-node filtering and nodelist_parse() for flexible input parsing. Node validity is verified using nodes_subset() to reject nodes without memory. Link: https://lore.kernel.org/20260707115411.1714314-3-zhen.ni@easystack.cn Signed-off-by: Zhen Ni <zhen.ni@easystack.cn> Tested-by: Zi Yan <ziy@nvidia.com> Acked-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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/page_owner: add print_mode filterZhen Ni
Patch series "mm/page_owner: add per-fd filter infrastructure for print_mode and NUMA filtering", v12. This patch series introduces per-file-descriptor filtering capabilities to the page_owner feature. Problem Statement ================= In production environments with large memory configurations (e.g., 250GB+), collecting page_owner information often results in files ranging from several gigabytes to over 10GB. This creates significant challenges: 1. Storage pressure on production systems 2. Difficulty transferring large files from production environments 3. Post-processing overhead with tools/mm/page_owner_sort.c The primary contributor to file size is redundant stack trace information. While the kernel already deduplicates stacks via stackdepot, page_owner retrieves and stores full stack traces for each page, only to deduplicate them again during post-processing. Additionally, in NUMA-aware environments (e.g., DPDK-based cloud deployments where QEMU processes are bound to specific NUMA nodes), OOM events are often node-specific rather than system-wide. Previously, page_owner could not filter by NUMA node, forcing users to collect and analyze data for all nodes. Solution ======== This patch series introduces a per-file-descriptor filter infrastructure with two initial filters: 1. **Print Mode Filter**: Outputs only stack handles instead of full stack traces. The handle-to-stack mapping can be retrieved from the existing show_stacks_handles interface. This dramatically reduces output size while preserving all allocation metadata. 2. **NUMA Node Filter**: Allows filtering pages by specific NUMA node(s) using flexible nodelist format, enabling targeted analysis of memory issues in NUMA-aware deployments. The per-fd design allows multiple concurrent page_owner reads with different filters, solving coordination issues in multi-user production environments. Implementation ============== The series is structured as follows: - Patch 1: Implement print_mode filter infrastructure * Add file->private_data to store per-fd filter state * Add .open, .release, and .write file operations * Support "stack", "handle", and "stack_handle" modes via "mode=" write commands - Patch 2: Implement NUMA node filter infrastructure * Add nid_filter field to per-fd state * Support flexible nodelist format via "nid=" write commands (single, multiple, ranges) * Validate nodes and reject non-existent nodes using nodes_subset() - Patch 3: Add page_owner_filter userspace tool * Manages per-fd filters via write() interface * Provides user-friendly command-line interface * Includes comprehensive input validation - Patch 4: Document filter features and usage Usage Example ============= Using the page_owner_filter tool with per-fd filters: # ./page_owner_filter -m stack_handle -n "0,2-3" -o page_owner.txt The tool opens /sys/kernel/debug/page_owner, sets filters via write(), then reads the filtered output to the specified file (or stdout). Sample print_mode output (showing handles only): Page allocated via order 0, mask 0x0(), pid 0, tgid 0 (swapper), ts 0 ns PFN 0x40000 type Unmovable Block 512 type Unmovable Flags 0x3fffe0000000000(node=0|zone=0|lastcpupid=0x1ffff) handle: 1048577 Page allocated via order 0, mask 0x252000(__GFP_NOWARN| __GFP_NORETRY|__GFP_COMP|__GFP_THISNODE), pid 0, tgid 0 (swapper), ts 0 ns PFN 0x40002 type Unmovable Block 512 type Unmovable Flags 0x23fffe0000000200(workingset|node=0|zone=0|lastcpupid=0x1ffff) handle: 1048577 This patch (of 4): Add a print_mode filter to page_owner that allows users to choose between printing stack traces, stack handles, or both, providing flexibility for different debugging and analysis scenarios. The filter provides three modes via page_owner: - Writing "mode=stack" prints stack traces for each page (default) - Writing "mode=handle" prints only the handle number - Writing "mode=stack_handle" prints both stack traces and handles The default stack mode maintains backward compatibility with existing usage, displaying complete stack traces for each page allocation. The handle mode dramatically reduces log size and improves performance by showing only the handle number instead of the full stack trace. Testing shows handle mode reduces output size by ~66% (84MB vs 244MB) and improves read performance by ~4.4x compared to full stack output. The mapping from handles to actual stack traces can be obtained via the show_stacks_handles interface. The stack_handle mode prints both stack traces and handles, making it easier to identify pages with the same allocation pattern by comparing handle numbers instead of comparing large stack traces. Example usage: # Using the page_owner_filter tool (recommended) ./page_owner_filter -m stack # Print only stack traces (default) ./page_owner_filter -m handle # Print only handles ./page_owner_filter -m stack_handle # Print both stack and handles Sample output (handle mode): Page allocated via order 0, migratetype Unmovable, gfp_mask 0x1100ca, pid 1, tgid 1 (systemd), ts 123456789 ns PFN 0x1000 type Unmovable Block 1 type Unmovable Flags 0x3fffe800000084(referenced|lru|active|private|node=0|zone=1) handle: 17432583 ... This implementation uses per-file-descriptor filter state stored in file->private_data, allowing each opener to have independent filter configuration. Link: https://lore.kernel.org/20260707115411.1714314-1-zhen.ni@easystack.cn Link: https://lore.kernel.org/20260707115411.1714314-2-zhen.ni@easystack.cn Signed-off-by: Zhen Ni <zhen.ni@easystack.cn> Tested-by: Zi Yan <ziy@nvidia.com> Acked-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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/migrate: use migrate_info field instead of privateShivank Garg
Add an unsigned long migrate_info member to the struct folio union and use it to store migration state (anon_vma pointer and FOLIO_WAS_* markers) instead of using folio->private. While at it, switch to bitwise OR. No functional change. [rdunlap@infradead.org: add missing kernel-doc for @migrate_info] Link: https://lore.kernel.org/20260717022146.1290242-1-rdunlap@infradead.org Link: https://lore.kernel.org/20260701-migrate-cleanups-prep-v2-3-d9e8f17130b1@amd.com Signed-off-by: Shivank Garg <shivankg@amd.com> Suggested-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Jonathan Cameron <jic23@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Huang Ying <ying.huang@linux.alibaba.com> Acked-by: Zi Yan <ziy@nvidia.com> Reviewed-by: SJ Park <sj@kernel.org> Signed-off-by: Randy Dunlap <rdunlap@infradead.org> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Dev Jain <dev.jain@arm.com> Cc: Gregory Price <gourry@gourry.net> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/migrate: fix stale list name in migrate_folios_move() commentShivank Garg
The return-value description in migrate_folios_move() still refers to unmap_folios, but that list no longer exists. Update this name to src_folios. Link: https://lore.kernel.org/20260701-migrate-cleanups-prep-v2-2-d9e8f17130b1@amd.com Signed-off-by: Shivank Garg <shivankg@amd.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Dev Jain <dev.jain@arm.com> Cc: Gregory Price <gourry@gourry.net> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com> Cc: Jonathan Cameron <jic23@kernel.org> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/migrate: rename page to folio leftoversShivank Garg
Patch series "mm/migrate: preparatory cleanups for batch copy and offload", v2. This is a small set of mm/migrate cleanups split out of the batch-copy and offload RFC [1], so they can be reviewed and merged independently ahead of that larger series. No functional change intended. This patch (of 3): Rename migrate_folio_undo_src()'s page_was_mapped parameter to was_mapped, unmap_and_move_huge_page() to unmap_and_move_hugetlb_folio(), its page_was_mapped variable to was_mapped and fix stale "page" wording in its comments. Also fix migrate_folio() kerneldoc to say "folio" instead of "page". Link: https://lore.kernel.org/20260701-migrate-cleanups-prep-v2-0-d9e8f17130b1@amd.com Link: https://lore.kernel.org/20260701-migrate-cleanups-prep-v2-1-d9e8f17130b1@amd.com Link: https://lore.kernel.org/all/20260428155043.39251-2-shivankg@amd.com [1] Signed-off-by: Shivank Garg <shivankg@amd.com> Suggested-by: Dev Jain <dev.jain@arm.com> Suggested-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Zi Yan <ziy@nvidia.com> Reviewed-by: SJ Park <sj@kernel.org> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Gregory Price <gourry@gourry.net> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: migrate_device: use walk_page_range_vma() in migrate_vma_collect()Kefeng Wang
migrate_vma_collect() uses walk_page_range() to walk the page table. Fortunately, migrate_vma_setup() already validates that the entire range falls within a single VMA. Since there is no .test_walk in migrate_vma_walk_ops and VM_PFNMAP was filtered by migrate_vma_setup(), it's safe to replace walk_page_range() with walk_page_range_vma() to eliminate an unnecessary find_vma() lookup. Link: https://lore.kernel.org/20260618092845.3905740-5-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Acked-by: Pedro Falcato <pfalcato@suse.de> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Gregory Price <gourry@gourry.net> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Ying Huang <ying.huang@linux.alibaba.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: mlock: use walk_page_range_vma() in mlock_vma_pages_range()Kefeng Wang
The mlock_vma_pages_range() uses walk_page_range() to walk the page table. Fortunately, the caller always passes start/end that falls within a single VMA, apply_vma_lock_flags() iterates per-VMA, and apply_mlockall_flags() passes the whole VMA. Since there is no .test_walk in mlock_walk_ops and VM_PFNMAP was filtered by vma_supports_mlock(), it's safe to replace walk_page_range() with walk_page_range_vma() to eliminate an unnecessary find_vma() lookup. Link: https://lore.kernel.org/20260618092845.3905740-4-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Gregory Price <gourry@gourry.net> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Ying Huang <ying.huang@linux.alibaba.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: mprotect: use walk_page_range_vma() in mprotect_fixup()Kefeng Wang
In mprotect_fixup(), the PROT_NONE PFN permission check uses walk_page_range() to walk the page table. Fortunately, the caller always passes start/end that falls within a single VMA, the do_mprotect_pkey() iterates per-VMA via for_each_vma_range(), and setup_arg_pages() passes the whole VMA. Note, walk_page_test() isn't called in walk_page_range_vma(), however, prot_none_test() in prot_none_walk_ops always return 0, so it's safe to replace walk_page_range() with walk_page_range_vma() to eliminate an unnecessary find_vma() lookup, also remove unneeded prot_none_test() too. Link: https://lore.kernel.org/20260618092845.3905740-3-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Cc: Gregory Price <gourry@gourry.net> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Ying Huang <ying.huang@linux.alibaba.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm: mincore: use walk_page_range_vma() in do_mincore()Kefeng Wang
Patch series "mm: convert to walk_page_range_vma() to eliminate find_vma()", v2. walk_page_range() performs a find_vma() lookup on each page table walk. For callers that already hold a valid VMA and operate on a known single-VMA range, this lookup is redundant. Replace walk_page_range() with walk_page_range_vma() where the caller guarantees single-VMA semantics. This patch (of 4): do_mincore() uses walk_page_range() to walk the page table. Fortunately, the caller always passes start/end that falls within a single VMA, so it's safe to use the walk_page_range_vma() in do_mincore() to eliminate an unnecessary find_vma() lookup. Unlike walk_page_range(), walk_page_range_vma() does not call walk_page_test(), which handles VM_PFNMAP by invoking ->pte_hole() to skip the page table walk. Without this check, PFNMAP PTEs would be treated as present by mincore_pte_range(), changing the returned residency status. Handle VM_PFNMAP explicitly in do_mincore() to preserve the original behavior. [akpm@linux-foundation.org: simplify comment, per Pedro] Link: https://lore.kernel.org/ajP9bQhmvR9OX0VE@pedro-suse Link: https://lore.kernel.org/20260618092845.3905740-1-wangkefeng.wang@huawei.com Link: https://lore.kernel.org/20260618092845.3905740-2-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Acked-by: Zi Yan <ziy@nvidia.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Cc: Alistair Popple <apopple@nvidia.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Gregory Price <gourry@gourry.net> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Ying Huang <ying.huang@linux.alibaba.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
10 daysmm/page_owner: use memcg_data snapshot to avoid TOCTOU in ↵Ye Liu
print_page_owner_memcg() print_page_owner_memcg() reads page->memcg_data via READ_ONCE() at the start to guard against tail pages and NULL data. However, it later re-reads page->memcg_data locklessly in two places: 1: page_memcg_check(page) 2: PageMemcgKmem(page) (via folio_memcg_kmem(), which includes VM_BUG_ON assertions for tail pages and MEMCG_DATA_OBJEXTS) If the page is concurrently freed and reallocated as a THP tail page or slab page between these calls, the VM_BUG_ON assertions can trigger on CONFIG_DEBUG_VM=y builds, crashing the kernel. Fix both TOCTOU issues by using the memcg_data snapshot throughout. Link: https://lore.kernel.org/20260714015117.78351-10-ye.liu@linux.dev Fixes: fcf8935832b8 ("mm/page_owner: print memcg information") Signed-off-by: Ye Liu <ye.liu@linux.dev> Reported-by: Sashiko <sashiko-bot@kernel.org> 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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>