mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
b1b7c045e808c761b1cc8c19b3040fadedda3fef
1463881
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b1b7c045e8 |
mm/hugetlb: initialize gigantic bootmem hugepage struct pages earlier
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:
|
||
|
|
89a4ae3276 |
powerpc/mm: fix wrong addr_pfn tracking in compound vmemmap population
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:
|
||
|
|
6e25c6a9c7 |
mm/hugetlb_vmemmap: fix __hugetlb_vmemmap_optimize_folios()
__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:
|
||
|
|
c0caeceb0c |
mm/hugetlb: fix boot panic with CONFIG_DEBUG_VM and HVO bootmem pages
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
|
||
|
|
b55cc244d0 |
percpu_ref: fix documentation of maximum value
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> |
||
|
|
52b71fe000 |
mm/page_alloc: drop flag-conversion "optimisation"
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>
|
||
|
|
375c63b649 |
writeback.h: fix a typo in the wbc_init_bio() description
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> |
||
|
|
eafe0dcdc0 |
mm: add writeback.h to docs build
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> |
||
|
|
e2c75342c2 |
mm/page_owner: document page_owner filter
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> |
||
|
|
1279c14f17 |
tools/mm: add page_owner_filter userspace tool
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> |
||
|
|
bed8003612 |
mm/page_owner: add NUMA node filter
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> |
||
|
|
8570b65220 |
mm/page_owner: add print_mode filter
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>
|
||
|
|
3dd5a633a0 |
mm/migrate: use migrate_info field instead of private
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> |
||
|
|
8d76257715 |
mm/migrate: fix stale list name in migrate_folios_move() comment
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> |
||
|
|
9aaf5aa244 |
mm/migrate: rename page to folio leftovers
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> |
||
|
|
9bde2240ec |
mm: migrate_device: use walk_page_range_vma() in migrate_vma_collect()
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> |
||
|
|
d4c63a378b |
mm: mlock: use walk_page_range_vma() in mlock_vma_pages_range()
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> |
||
|
|
334509572d |
mm: mprotect: use walk_page_range_vma() in mprotect_fixup()
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> |
||
|
|
8fb1ad47dc |
mm: mincore: use walk_page_range_vma() in do_mincore()
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> |
||
|
|
90f095b816 |
mm/page_owner: use memcg_data snapshot to avoid TOCTOU in 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:
|
||
|
|
4fd1c85cc0 |
mm/page_owner: clamp skip_buddy_pages() PFN advance at 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. If this bogus order is <= MAX_PAGE_ORDER, skip_buddy_pages() would arbitrarily advance the PFN, potentially jumping past a MAX_ORDER_NR_PAGES boundary 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(), skipping the boundary could cause pfn_to_page() to access an unmapped mem_section. Clamp the advance so it never crosses the next MAX_ORDER_NR_PAGES boundary. This is safe for all three callers: the pageblock-iterating ones already handle boundary transitions in their outer loops, and for read_page_owner() the worst case is one extra PageBuddy check per 1024 pages when a bogus order would otherwise push past the boundary. Link: https://lore.kernel.org/20260714015117.78351-9-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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
f0bb69130e |
mm/page_owner: drop redundant page_owner prefix from static symbols
All of these symbols are file-scoped (static) in page_owner.c, so the page_owner_ prefix is pure noise. Rename them to shorter, still-clear names: page_owner_stack_op -> stack_op page_owner_stack_open -> stack_open page_owner_stack_fops -> stack_fops page_owner_pages_threshold -> pages_threshold page_owner_threshold_get -> threshold_get page_owner_threshold_set -> threshold_set page_owner_threshold_fops -> threshold_fops No functional change. Link: https://lore.kernel.org/20260714015117.78351-8-ye.liu@linux.dev Signed-off-by: Ye Liu <ye.liu@linux.dev> 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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
1f5af031ff |
mm/page_owner: move free_ts_nsec output to free section in __dump_page_owner()
The free_ts_nsec field is a free-event timestamp, but it was printed in the allocation summary line alongside ts_nsec (allocation time). Move it to the free section where it logically belongs, together with free_pid and free_tgid. This also makes __dump_page_owner() consistent with print_page_owner(), which only prints ts_nsec in the allocation summary. The output now groups all free-related information (pid, tgid, timestamp, stack trace) in one place. No functional change except output formatting. Link: https://lore.kernel.org/20260714015117.78351-7-ye.liu@linux.dev Signed-off-by: Ye Liu <ye.liu@linux.dev> 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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
c1c94cf658 |
mm/page_owner: add missing newline to count_threshold format string
The DEFINE_SIMPLE_ATTRIBUTE format string for page_owner_threshold_fops is missing a trailing \n. simple_attr_read() uses scnprintf() with the format string, which does not append a newline, so reading /sys/kernel/debug/page_owner_stacks/count_threshold produces output without a terminating newline. Add the missing \n to match the standard debugfs attribute convention. Link: https://lore.kernel.org/20260714015117.78351-6-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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
e90ed51908 |
mm/page_owner: hoist CONFIG_MEMCG to function level for print_page_owner_memcg()
The print_page_owner_memcg() function has CONFIG_MEMCG guarding its entire
body via #ifdef inside the function, which leaves a no-op { return ret; }
when the config is disabled. Hoist the #ifdef to the top level so the
real implementation and the empty stub are two clearly separated
definitions.
No functional change.
Link: https://lore.kernel.org/20260714015117.78351-5-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: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||
|
|
c95dc0a84b |
mm: use enum migrate_reason instead of int for migration reason parameters
Replace all 'int reason' function parameters that carry migrate_reason
values with the proper 'enum migrate_reason' type. This makes the intent
explicit and leverages compiler type checking. The affected subsystems
are:
- page_owner: __folio_set_owner_migrate_reason(),
folio_set_owner_migrate_reason()
- migrate: migrate_pages(), migrate_pages_sync(),
migrate_pages_batch(), migrate_folios_move(),
migrate_hugetlbs(), unmap_and_move_huge_page()
- hugetlb: move_hugetlb_state(), htlb_allow_alloc_fallback()
- trace: mm_migrate_pages and mm_migrate_pages_start events
The 'short last_migrate_reason' struct field and internal helper parameter
in page_owner are intentionally left as 'short' since they store per-page
metadata where size matters.
No functional change.
Link: https://lore.kernel.org/20260714015117.78351-4-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>
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@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>
|
||
|
|
7eeed888c9 |
mm/page_owner: add MR_NEVER to enum migrate_reason and use it for last_migrate_reason
The last_migrate_reason field uses -1 as a sentinel value to mean "no migration has happened". Replace the four bare -1 occurrences by adding a proper MR_NEVER member to enum migrate_reason, defining a corresponding "never_migrated" string in the MIGRATE_REASON trace macro, and updating the GDB page_owner script to use MR_NEVER instead of the hardcoded -1 so that lx-dump-page-owner does not incorrectly report unmigrated pages as migrated. No functional change. Link: https://lore.kernel.org/20260714015117.78351-3-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: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: David Hildenbrand (Arm) <david@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
53472eb262 |
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> |
||
|
|
cdf95d6b33 |
mm/kmemleak: stop the per-cpu and struct page scans early too
The per-cpu and struct page scan loops have no reschedule-stop check of their own: once a scan is interrupted they keep calling scan_block() for every remaining block, which scans nothing useful. Propagate scan_block()'s interrupted status through scan_large_block() and break both loops as soon as it is set. Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-3-acecd7d7fd92@debian.org Signed-off-by: Breno Leitao <leitao@debian.org> Suggested-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Lance Yang <lance.yang@linux.dev> Cc: Qian Cai <cai@lca.pw> Cc: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
eb11f56eec |
mm/kmemleak: stop the task stack scan early when interrupted
scan_block() already checks scan_should_stop() for every pointer and bails out of the current block, but the task stack walk cannot tell and keeps issuing a separate scan_should_stop() between every task. Return that status from scan_block() and use it as the task stack loop condition, so the walk stops as soon as a scan is interrupted. Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-2-acecd7d7fd92@debian.org Signed-off-by: Breno Leitao <leitao@debian.org> Suggested-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Lance Yang <lance.yang@linux.dev> Cc: Qian Cai <cai@lca.pw> Cc: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
5d10d4e19e |
mm/kmemleak: avoid soft lockup when scanning task stacks
Patch series "mm/kmemleak: avoid soft lockup when scanning task", v3.
kmemleak_scan() scans every task stack under one rcu_read_lock() with no
reschedule point, which can trip the soft lockup watchdog on hosts with
very many threads.
That prints the following message, depending on the workload+host
configuration:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537]
scan_block
kmemleak_scan
kmemleak_scan_thread
kthread
Patch 1 walks the tasks with find_ge_pid() so the scan reschedules between
tasks
Patches 2-3 let the scan loops stop early once a scan is interrupted.
This patch (of 3):
kmemleak_scan() walks every thread and scans its kernel stack under a
single rcu_read_lock() with no reschedule point. On a host with very many
threads -- amplified by KASAN/lockdep in debug builds -- this loop can hog
a CPU long enough to trip the soft lockup watchdog:
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537]
scan_block
kmemleak_scan
kmemleak_scan_thread
kthread
A cond_resched() cannot be added directly: the loop runs inside an RCU
read-side critical section.
Walk the tasks one PID at a time with find_ge_pid(), taking the RCU read
lock only to look up and pin each task. The stack is then scanned with no
lock held, so cond_resched() runs between tasks and the scan stops early
on scan_should_stop(). This follows the next_tgid()/task_seq_get_next()
iteration pattern and keeps each RCU critical section short.
Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-0-acecd7d7fd92@debian.org
Link: https://lore.kernel.org/20260615-kmemleak-stack-resched-v3-1-acecd7d7fd92@debian.org
Fixes:
|
||
|
|
aa38f2454b |
mm: hugetlb: correct CONFIG_CGROUP_HUGETLB macro name in comment
A comment in <linux/hugetlb_cgroup.h> incorrectly refers to CONFIG_MEM_RES_CTLR_HUGETLB, which has never existed in the kernel, instead of CONFIG_CGROUP_HUGETLB. Correct it. Discovered while searching for CONFIG_* symbols referenced in code but not defined in any Kconfig file. Link: https://lore.kernel.org/20260616000135.62815-1-enelsonmoore@gmail.com Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Cc: Anthony Yznaga <anthony.yznaga@oracle.com> Cc: Muchun Song <muchun.song@linux.dev> Cc: Oscar Salvador <osalvador@suse.de> Cc: Pedro Falcato <pfalcato@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
24e9b62985 |
mm/vmalloc: use more common error handling code in pcpu_get_vm_areas()
Use an existing label once more so that a bit of exception handling can be better reused at the end of this function implementation. This issue was detected by using the Coccinelle software. Link: https://lore.kernel.org/453375c4-c3ca-4e6f-8880-0e6ff3c74ee3@web.de Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> Reviewed-by: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: Alexander Potapenko <glider@google.com> Cc: Daniel Axtens <dja@axtens.net> Cc: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
73e28dccd0 |
arch_numa: remove redundant nodemask clears in numa_init()
numa_init() clears numa_nodes_parsed, node_possible_map and
node_online_map, then calls numa_memblks_init(), which clears the same
nodemasks. Nothing uses them in between.
These clears have been redundant since commit
|
||
|
|
d623ed9ba0 |
csky: implement flush_cache_vmap() in C
To avoid getting an unused-var warning from unsigned long start = something; ... flush_cache_vmap(start, ...); Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202606291606.9h8aGniQ-lkp@intel.com/ Reviewed-by: Guo Ren <guoren@kernel.org> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Andrew Donnellan <ajd@linux.ibm.com> Cc: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: David Hildenbrand <david@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: Leo Yan <leo.yan@arm.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Uladzislau Rezki <urezki@gmail.com> Cc: Wen Jiang <jiangwen6@xiaomi.com> Cc: Wen Jiang <jiangwenxiaomi@gmail.com> Cc: Will Deacon <will@kernel.org> Cc: Xueyuan Chen <xueyuan.chen21@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
cdea9364e4 |
mm/page_alloc: don't build vm_numa_stat_key if CONFIG_NUMA=n
vm_numa_stat_key is only exported if CONFIG_NUMA is set, so avoid the following warning by guarding it in an #ifdef on CONFIG_NUMA: mm/page_alloc.c:165:1: warning: symbol 'vm_numa_stat_key' was not declared. Should it be static? Link: https://lore.kernel.org/20260618100614.1321950-1-ben.dooks@codethink.co.uk Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Zi Yan <ziy@nvidia.com> Reviewed-by: SeongJae Park <sj@kernel.org> Cc: Brendan Jackman <jackmanb@google.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
a35d8872da |
mm: remove PageTransCompound()
Remove the last user of PageTransCompound() in ksm and get rid of PageTransCompound(). Link: https://lore.kernel.org/20260618113523.3913307-1-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Xu Xin <xu.xin16@zte.com.cn> Tested-by: Xu Xin <xu.xin16@zte.com.cn> Acked-by: Zi Yan <ziy@nvidia.com> Reviewed-by: SeongJae Park <sj@kernel.org> Cc: Chengming Zhou <chengming.zhou@linux.dev> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
8725ae13f0 |
mm/percpu: avoid IO/FS reclaim in backing allocations
Commit |
||
|
|
17fcdd8699 |
mm/percpu: make cached pages lookup explicit
pcpu_depopulate_chunk() only needs the temporary pages array that was already allocated by an earlier successful population attempt. Passing GFP_KERNEL to pcpu_get_pages() in this path is misleading because the depopulation path is not expected to allocate the array. Teach pcpu_get_pages() to treat a zero gfp mask as a cached-only lookup and add pcpu_get_pages_cached() for that use case. This keeps allocation on the populate path tied to the caller supplied GFP mask while making the depopulate path's dependency on the cached array explicit. Link: https://lore.kernel.org/20260618130414.96383-4-kaitao.cheng@linux.dev Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn> Suggested-by: Dennis Zhou <dennis@kernel.org> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Christoph Lameter <cl@gentwo.org> Cc: Pedro Falcato <pfalcato@suse.de> Cc: Shivam Kalra <shivamkalra98@zohomail.in> Cc: Tejun Heo <tj@kernel.org> Cc: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
881adc51b2 |
mm/percpu: honor GFP constraints when populating chunks
pcpu_alloc_noprof() derives pcpu_gfp from the caller supplied GFP mask and passes it down to pcpu_populate_chunk(). pcpu_alloc_pages() already uses that mask for backing page allocation. However, the populate slow path still has internal allocations and page table allocations which can lose the caller's allocation context. The temporary pages array is allocated by pcpu_get_pages() with GFP_KERNEL, and pcpu_map_pages() maps the backing pages through vmap_pages_range_noflush() using GFP_KERNEL. The latter can allocate vmalloc page tables implicitly, so a caller which deliberately uses GFP_NOFS or GFP_NOIO can still enter FS or IO reclaim while populating a percpu chunk. This has the same concern as chunk creation: callers such as blk-cgroup may use GFP_NOIO because they hold locks which can be involved in queue freeze or IO reclaim dependencies. If an allocation reaches the percpu slow path and needs to populate previously unbacked pages, the internal GFP_KERNEL allocations can defeat that context. One possible case is blk-cgroup after commit |
||
|
|
dec068de6d |
mm/vmalloc: honor GFP constraints in pcpu_get_vm_areas()
Patch series "mm/percpu: Fix possible NOFS/NOIO reclaim recursion", v4. Commit |
||
|
|
5339ec29f9 |
mm: replace __ASSEMBLY__ with __ASSEMBLER__ in memory management header files
While the GCC and Clang compilers already define __ASSEMBLER__ automatically when compiling assembly code, __ASSEMBLY__ is a macro that only gets defined by the Makefiles in the kernel. This can be very confusing when switching between userspace and kernelspace coding, or when dealing with uapi headers that rather should use __ASSEMBLER__ instead. So let's standardize now on the __ASSEMBLER__ macro that is provided by the compilers. This is a completely mechanical patch (done with a simple "sed -i" statement). Link: https://lore.kernel.org/20260619131830.229804-1-thuth@redhat.com Signed-off-by: Thomas Huth <thuth@redhat.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Barry Song <baohua@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Suren Baghdasaryan <surenb@google.com> 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> |
||
|
|
32cd1afeca |
mm/filemap: reduce unnecessary xarray lookups in filemap_get_folios_contig()
Apply the same optimization used in filemap_get_read_batch() by moving the boundary check from the loop condition to before xas_next(), avoiding an unnecessary xarray lookup and reducing branches in the fast path. Link: https://lore.kernel.org/20260620062446.351475-3-chizhiling@163.com Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn> Reviewed-by: Jan Kara <jack@suse.cz> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
e1c345582c |
mm/filemap: reduce unnecessary xarray lookups when read cached pages
Patch series "mm/filemap: reduce unnecessary xarray lookups". This series optimizes xarray lookups in filemap by avoiding redundant iterations after obtaining the last needed folio. The boundary check is moved to before advancing the xarray iterator, eliminating unnecessary lookups and branches in the fast path. This reduces the overhead of filemap_get_read_batch() from 2.91% to 2.53% in 4k read tests. This patch (of 2): When reading small amounts of data from the page cache, only a single folio is typically returned from filemap_read_get_batch(). In this case, calling xas_advance() or xas_next() after adding the folio to the batch is unnecessary and only introduces extra branches. The same issue exists for large reads, where one additional xarray walk is always performed before termination. Quit the loop once we get the last folio in the range, so the final redundant xarray advancement can be avoided. The xas_next() does not update xa_index when xas->xa_node is set to XAS_RESTART, so the put and retry path would not update xa_index, hence the warning should therefore never trigger. During the 4k reads test, the overhead of this function dropped from 2.91% to 2.53%. Link: https://lore.kernel.org/20260620062446.351475-2-chizhiling@163.com Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn> Suggested-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Jan Kara <jack@suse.cz> Cc: Chi Zhiling <chizhiling@kylinos.cn> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
094470f3f4 |
mm/lruvec: trace LRU add drains and drain-all requests
LRU add batches can be drained before they reach capacity. This can be a source of LRU lock contention, but it is not currently possible to attribute these drains to callers with existing tracepoints. Add mm_lru_add_drain to report the CPU and lru_add batch count when an lru_add batch is drained. This allows tracing to distinguish full drains from partial drains and attribute them to the calling stack. Add mm_lru_add_drain_all to capture callers of __lru_add_drain_all and whether they set the force flag for all CPUs. The tracepoint resembles the signature of the enclosing function, but is needed because of potential inlining. Note that DECLARE_TRACE() is used for these new trace hooks to avoid creating a new trace event ABI. Link: https://lore.kernel.org/20260622185127.24579-1-jp.kobryn@linux.dev Signed-off-by: JP Kobryn <jp.kobryn@linux.dev> Reviewed-by: Barry Song <baohua@kernel.org> Acked-by: Shakeel Butt <shakeel.butt@linux.dev> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Chris Li <chrisl@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> 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> |
||
|
|
4ac732c370 |
mm: memcg: remove stray text from obj_stock_pcp comment
A patch filename was accidentally inserted into the comment describing the nr_bytes field of struct obj_stock_pcp. Remove it. No functional change. Link: https://lore.kernel.org/20260623082614.81621-1-guopeng.zhang@linux.dev Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn> Acked-by: Harry Yoo (Oracle) <harry@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
253ed912fe |
mm/memory-failure: remove redundant initialization for hw_memory_failure
The static variable 'hw_memory_failure' is implicitly initialized to false. Remove the explicit initialization to follow the Linux kernel coding style. Link: https://lore.kernel.org/20260623114743.4565-3-igorpetindev@gmail.com Signed-off-by: Igor Putko <igorpetindev@gmail.com> Reviewed-by: SeongJae Park <sj@kernel.org> Reviewed-by: Lance Yang <lance.yang@linux.dev> Acked-by: Miaohe Lin <linmiaohe@huawei.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Konovalov <andreyknvl@gmail.com> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Naoya Horiguchi <nao.horiguchi@gmail.com> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
731a624641 |
mm/kasan: remove redundant initialization for kasan_flag_write_only
Patch series "mm: remove redundant static variable initializations". This series removes explicit initializations of static bool variables to false within the mm/ subsystem. In C, static variables without explicit initialization are implicitly placed in the .bss section and initialized to zero/false by default. Removing these explicit initializations follows the Linux kernel coding style and avoids cluttering the data section. This patch (of 2): The static variable 'kasan_flag_write_only' is implicitly initialized to false. Remove the explicit initialization to follow the Linux kernel coding style. Link: https://lore.kernel.org/20260623114743.4565-1-igorpetindev@gmail.com Link: https://lore.kernel.org/20260623114743.4565-2-igorpetindev@gmail.com Signed-off-by: Igor Putko <igorpetindev@gmail.com> Reviewed-by: SeongJae Park <sj@kernel.org> Reviewed-by: Lance Yang <lance.yang@linux.dev> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Konovalov <andreyknvl@gmail.com> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Miaohe Lin <linmiaohe@huawei.com> Cc: Naoya Horiguchi <nao.horiguchi@gmail.com> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
8a28b50d6f |
mm/mprotect: drop 'sub' from batching context
Shorten the name of page_anon_exclusive_sub_batch by dropping the "sub-batch" context - the function itself doesn't need this context. Similarly, drop "sub" from sub_batch_idx, it is unnecessary and the usage is clear enough. Link: https://lore.kernel.org/20260623125723.2503832-3-dev.jain@arm.com Signed-off-by: Dev Jain <dev.jain@arm.com> Reviewed-by: Lance Yang <lance.yang@linux.dev> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Baoquan He <baoquan.he@linux.dev> 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: Ryan Roberts <ryan.roberts@arm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
||
|
|
3ade884239 |
mm/swap: rename subpage->page in folio_dup_swap/folio_put_swap
Patch series "mm: drop "sub" prefix from various places". Patch 1 converts subpage->page : folios have pages, not subpages. Patch 2 drops "sub" from a function and a variable because the context is clear enough. This patch (of 2): Folios have pages, not subpages. Rename 'subpage' parameters to 'page'. Link: https://lore.kernel.org/20260623125723.2503832-1-dev.jain@arm.com Link: https://lore.kernel.org/20260623125723.2503832-2-dev.jain@arm.com Signed-off-by: Dev Jain <dev.jain@arm.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Lance Yang <lance.yang@linux.dev> Acked-by: Pedro Falcato <pfalcato@suse.de> Reviewed-by: Lorenzo Stoakes <ljs@kernel.org> Reviewed-by: Nhat Pham <nphamcs@gmail.com> Reviewed-by: Kairui Song <kasong@tencent.com> Reviewed-by: Barry Song <baohua@kernel.org> Cc: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Chris Li <chrisl@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |