mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
3c453bddacd4c04ecb38cf79dbfa41e7dfe0531b
1463922
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3c453bddac |
mm/damon/sysfs-schemes: kobject_del() scheme filter dirs
On CONFIG_DEBUG_KOBJECT_RELEASE enabled kernel, lack of kobject_del()
could cause directories creation failures due to the name conflicts. Fix
those issues for scheme filter directories by adding kobject_del() calls.
Link: https://lore.kernel.org/20260628220121.97360-6-sj@kernel.org
Fixes:
|
||
|
|
f3ec327121 |
mm/damon/sysfs-schemes: kobject_del() scheme region dirs
On CONFIG_DEBUG_KOBJECT_RELEASE enabled kernel, lack of kobject_del()
could cause directories creation failures due to the name conflicts. Fix
those issues for scheme region directories by adding kobject_del() calls.
This issue was discovered [1] by Sashiko, though its analysis was
partially incorrect.
Link: https://lore.kernel.org/20260628220121.97360-5-sj@kernel.org
Link: https://lore.kernel.org/20260517205828.6204-1-sj@kernel.org [1]
Fixes:
|
||
|
|
05fb6ac98c |
mm/damon/sysfs-schemes: kobject_del() scheme dirs
On CONFIG_DEBUG_KOBJECT_RELEASE enabled kernel, lack of kobject_del()
could cause directories creation failures due to the name conflicts. Fix
those issues for scheme directories by adding kobject_del() calls.
Link: https://lore.kernel.org/20260628220121.97360-4-sj@kernel.org
Fixes:
|
||
|
|
2603ef6f6e |
mm/damon/sysfs: kobject_del() region and target (error) dirs
On CONFIG_DEBUG_KOBJECT_RELEASE enabled kernel, lack of kobject_del()
could cause directories creation failures due to the name conflicts. Fix
those issues for the normal creation path of region directories and the
error path of target directories, by adding kobject_del() calls.
Link: https://lore.kernel.org/20260628220121.97360-3-sj@kernel.org
Fixes:
|
||
|
|
263af33a72 |
mm/damon/sysfs: kobject_del() target (normal), context and kdamond dirs
Patch series "mm/damon/sysfs: kobject_del() directories that users can
create/remove".
DAMON sysfs interface allows users to create and remove arbitrary number
of directories on sysfs, using a few files having 'nr_' prefix. For
example, 'nr_kdamonds'. When the user writes a number 'N' to the files,
directories having name starting from '0' to 'N - 1' are created in the
same directory. The pre-existing number-named directories are removed
before creating the new directories.
For the removal of the existing directories, DAMON sysfs interface use
only kobject_put(). Because DAMON sysfs interface is the only kernel
component that manages the directories, there is no problem in normal
situations. However, if CONFIG_DEBUG_KOBJECT_RELEASE is enabled, the
removal of dirs are delayed. Let's suppose a user writes a non-zero
number to the 'nr_*' files while there are pre-existing number-named
directories, on the config enabled kernel. DAMON sysfs interface
decreases the reference counts of the existing directories and immediately
creates new directories. Because the removal of the sysfs directories is
delayed, it shows some pre-existing directories of the same names when it
tries to create the new directories, and fails.
For example, the issue can be triggered like below:
# grep DEBUG_KOBJECT_RELEASE /boot/config-$(uname -r)
CONFIG_DEBUG_KOBJECT_RELEASE=y
# ls
nr_kdamonds
# echo 1 > nr_kdamonds
# echo 1 > nr_kdamonds
bash: echo: write error: File exists
# dmesg
[...]
[ 300.880458] kobject: kobject_add_internal failed for 0 with -EEXIST, don't try to register things with the same name in the same directory.
[...]
Some of the error handling paths of the directories also lack the
kobject_del() call. If the user uses nr_* file right after the errors,
similar issues can happen.
This doesn't cause catastrophic issues like kernel panics or memory
corruptions. Users can work around by removing all directories first
(write 0 to the nr_* files) and then create new directories after
confirming the old directories are gone. But, this is definitely a bug
that causes a bad user experience.
Fix the issues by calling kobject_del() before creating new directories.
This patch (of 11)
On CONFIG_DEBUG_KOBJECT_RELEASE enabled kernel, lack of kobject_del()
could cause directories creation failures due to the name conflicts. Fix
those issues for normal creation paths of target, context and kdamond
directories, and error paths of context and kdamond directories by adding
kobject_del() calls.
Note that this fix for target directories is not complete since it has a
similar issue in the damon_sysfs_targets_add_dirs() error path. Because
the normal path issue and the error path issue are introduced by different
commits, this commit is fixing only the normal path issue. A commit for
the error path will be added next.
Link: https://lore.kernel.org/20260628220121.97360-1-sj@kernel.org
Link: https://lore.kernel.org/20260628220121.97360-2-sj@kernel.org
Fixes:
|
||
|
|
a73fa45d3f |
samples/damon/prcl: stop and free damon ctx when damon_call() fails
damon_sample_prcl_start() calls damon_call() right after damon_start() is
succeeded. The kdamond that has started by the damon_start() could be
terminated by itself before or in the middle of the damon_call()
execution. There could be multiple reasons for such a stop including
monitoring target process termination and kdamond_fn() internal memory
allocation failures. In the case, damon_call() will fail and return an
error without cleaning up the DAMON context object. The
damon_sample_prcl_start() caller assumes it would clean up the object,
though. When the user requests to start DAMON again,
damon_sample_prcl_start() is called again, allocates a new DAMON context
object and overwrites the pointer for the previous object. As a result,
the previous context object is leaked.
Safely stop the kdamond and deallocate the context object when the failure
is returned. Note that the kdamond should be stopped first, because
damon_call() failure means not complete termination of the kdamond but
only the fact that the termination process has started.
The user impact shouldn't be that significant because the race is not easy
to happen, and only up to one DAMON context object can be leaked per race.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-7-sj@kernel.org
Link: https://lore.kernel.org/20260610035214.4850-1-sj@kernel.org [1]
Fixes:
|
||
|
|
a2c6fa6c23 |
samples/damon/wsse: stop and free damon ctx when damon_call() fails
damon_sample_wsse_start() calls damon_call() right after damon_start() is
succeeded. The kdamond that has started by the damon_start() could be
terminated by itself before or in the middle of the damon_call()
execution. There could be multiple reasons for such a stop including
monitoring target process termination and kdamond_fn() internal memory
allocation failures. In the case, damon_call() will fail and return an
error without cleaning up the DAMON context object. The
damon_sample_wsse_start() caller assumes it would clean up the object,
though. When the user requests to start DAMON again,
damon_sample_wsse_start() is called again, allocates a new DAMON context
object and overwrites the pointer for the previous object. As a result,
the previous context object is leaked.
Safely stop the kdamond and deallocate the context object when the failure
is returned. Note that the kdamond should be stopped first, because
damon_call() failure means not complete termination of the kdamond but
only the fact that the termination process has started.
The user impact shouldn't be that significant because the race is not easy
to happen, and only up to one DAMON context object can be leaked per race.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-6-sj@kernel.org
Link: https://lore.kernel.org/20260610034828.4632-1-sj@kernel.org [1]
Fixes:
|
||
|
|
9dc5b6d66f |
samples/damon/mtier: handle damon_stop() failure
damon_sample_mtier_stop() assumes its damon_stop() call will always
successfully stops the two DAMON contexts. Hence it deallocates the two
DAMON contexts after the damon_stop() call. However, if a given context
is already stopped, damon_stop() fails and returns an error while letting
the DAMON contexts that have not yet stopped keep running. This kind of
unexpected early DAMON context stops could happen due to memory allocation
failures in kdamond_fn(). Because damon_sample_mtier_stop() just
deallocates all DAMON contexts with damon_target and damon_region objects
that are linked to the contexts, the execution of the unstopped DAMON
context (kdamond) ends up using the memory that freed (use-after-free).
Fix the issue by separating the damon_stop() to be invoked per context.
Note that DAMON_SYSFS also allows multiple DAMON contexts execution. But,
it calls damon_stop() for each context one by one. Hence this issue is
only in mtier.
For the long term, it would be better to refactor damon_stop() to always
ensure stopping all contexts regardless of the failures in the middle.
Make this fix in the current way, though, to keep it simple and easy to
backport. I will do the refactoring later.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-5-sj@kernel.org
Link: https://lore.kernel.org/20260609014219.3013-1-sj@kernel.org [1]
Fixes:
|
||
|
|
c7230d08ee |
samples/damon/mtier: handle damon_start() failure
damon_sample_mtier_start() callers assume it will clean up resources when
it fails. And the function does the cleanup for context buildup failures.
However, it is not doing the cleanup for damon_start() failure.
As a result, when damon_start() fails, it could leak the memory for DAMON
context. Also, if damon_start() fails for only the second context, the
first context will indefinitely run, and avoid starting other DAMON
contexts since it is running in the exclusive mode. Stop possibly started
DAMON context and free the contexts in case of the failure to fix the
issues.
Note that the issue can reliably be reproduced because the module calls
damon_start() in the exclusive mode. For example,
$ sudo damo start
$ echo Y | sudo tee /sys/module/damon_sample_mtier/parameters/enabled
$ sudo cat /proc/allocinfo | grep damon_new_ctx
Because the first command is running another DAMON instance, the second
command fails the damon_start() call because the new DAMON instance cannot
exclusively run. And without this fix, by repeating the second and the
third commands above, we can show the memory consumption is only
increasing due to the leaks. It requires the sudo permission though.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-4-sj@kernel.org
Link: https://lore.kernel.org/20260608112455.274231F00893@smtp.kernel.org [1]
Fixes:
|
||
|
|
8b72434922 |
samples/damon/prcl: handle damon_start() failure
damon_sample_prcl_start() callers assume it will clean up resources when
it fails. And the function does the cleanup for context buildup failures.
However, it is not doing the cleanup for damon_start() failure. As a
result, when damon_start() fails, it leaks the memory for DAMON context.
Free the context in case of the failure to fix the issues.
Note that the issue can reliably be reproduced because the module calls
damon_start() in the exclusive mode. For example,
$ sudo damo start
$ echo $$ | sudo tee /sys/module/damon_sample_prcl/parameters/target_pid
$ echo Y | sudo tee /sys/module/damon_sample_prcl/parameters/enabled
$ sudo cat /proc/allocinfo | grep damon_new_ctx
Because the first command is running another DAMON instance, the third
command fails the damon_start() call because the new DAMON instance cannot
exclusively run. And without this fix, by repeating the third and the
fourth commands above, we can show the memory consumption is only
increasing due to the leaks. It requires the sudo permission though.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-3-sj@kernel.org
Link: https://lore.kernel.org/20260609145814.70163-1-sj@kernel.org [1]
Fixes:
|
||
|
|
e4742be45e |
samples/damon/wsse: handle damon_start() failure
Patch series "samples/damon: handle damon_{start,stop}() failures".
All DAMON sample modules are not correctly handling failures from
damon_start(). Among those, mtier also has an additional problem for
handling of damon_stop() failures. wsse and prcl also have a problem in
their damon_call() failure handling. As a result, memory leaks, next
DAMON operation disruptions, and use-after-free can happen. Fix those.
Note that only the damon_start() failure caused issues can reliably be
reproduced. Reproducing those issues require the admin permission,
though.
This patch (of 6):
damon_sample_wsse_start() callers assume it will clean up resources when
it fails. And the function does the cleanup for context buildup failures.
However, it is not doing the cleanup for damon_start() failure. As a
result, when damon_start() fails, it leaks the memory for DAMON context.
Free the context in case of the failure to fix the issues.
Note that the issue can reliably be reproduced because the module calls
damon_start() in the exclusive mode. For example,
$ sudo damo start
$ echo $$ | sudo tee /sys/module/damon_sample_wsse/parameters/target_pid
$ echo Y | sudo tee /sys/module/damon_sample_wsse/parameters/enabled
$ sudo cat /proc/allocinfo | grep damon_new_ctx
Because the first command is running another DAMON instance, the third
command fails the damon_start() call because the new DAMON instance cannot
exclusively run. And without this fix, by repeating the third and the
fourth commands above, we can show the memory consumption is only
increasing due to the leaks. It requires the sudo permission though.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260628215447.96166-2-sj@kernel.org
Link: https://lore.kernel.org/20260609145814.70163-1-sj@kernel.org [1]
Fixes:
|
||
|
|
aaa98b100e |
mm/vmstat: avoid taking zone lock in /proc/buddyinfo reads
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> |
||
|
|
a4519e5b64 |
mm/swap_state: remove unnecessary lru_add_drain() from readahead
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
|
||
|
|
baff6d2d27 |
mm: constify oom_control, scan_control, and alloc_context nodemask
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> |
||
|
|
567c26a132 |
include/linux/swap.h: remove unused leftovers
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> |
||
|
|
5a00cae64d |
mm/damon/core: reduce kernel stack usage
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> |
||
|
|
3c77682d80 |
mm: move alloc tag to mm
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> |
||
|
|
7c717f37ee |
MAINTAINERS: move inactive maintainer to CREDITS
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> |
||
|
|
0abea609f3 |
mm/zsmalloc: document free_zspage helper variants
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> |
||
|
|
7ef28e8b81 |
mm/zsmalloc: drop class lock before freeing zspage
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> |
||
|
|
59e88952a8 |
mm/zsmalloc: drop pool->lock from zs_free on 64-bit systems
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> |
||
|
|
9909b088b1 |
mm/zsmalloc: encode class index in obj value for lockless class lookup
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>
|
||
|
|
f078b0a072 |
mm: annotate data-race in cpu_needs_drain()
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> |
||
|
|
83fd5cbe65 |
radix-tree: add/correct some kernel-doc
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> |
||
|
|
31fd8876a3 |
tmpfs: zero unused folio tail for long symlinks
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:
|
||
|
|
efcf17453c |
mm/kmemleak: skip the remaining scan phases when interrupted
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> |
||
|
|
6d098029de |
mm/mm_init: fold __init_page_from_nid() into __init_deferred_page()
__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> |
||
|
|
8669383759 |
mm/hugetlb: remove unused bootmem cma field
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> |
||
|
|
ec1adc14c1 |
mm/sparse-vmemmap: remove sparse_vmemmap_init_nid_late()
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> |
||
|
|
4753a8220a |
mm/hugetlb: remove obsolete bootmem cross-zone checks
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> |
||
|
|
51d73513dd |
mm/hugetlb_vmemmap: move bootmem HVO setup to early init
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> |
||
|
|
20549ccf4d |
mm/hugetlb: free cross-zone bootmem gigantic pages after allocation
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> |
||
|
|
27ca02e689 |
mm/hugetlb: refactor early boot gigantic hugepage allocation
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> |
||
|
|
7e25033415 |
mm/hugetlb_cma: validate hugetlb CMA range by zone at reserve time
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> |
||
|
|
133b57fee9 |
mm/sparse: move sparse_vmemmap_init_nid_late() into sparse_init_nid()
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> |
||
|
|
37424eab6d |
mm/mm_init: remove set_pageblock_order() call from sparse_init()
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> |
||
|
|
1221a19f2b |
mm/mm_init: defer hugetlb reservation until after zone initialization
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> |
||
|
|
ee6192a2c4 |
mm/mm_init: defer sparse_init() until after zone initialization
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> |
||
|
|
8e4ee7b1bd |
mm/sparse: move subsection_map_init() into sparse_init()
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> |
||
|
|
b3ef855262 |
mm/sparse: panic on memmap and usemap allocation failure
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> |
||
|
|
9c29f83d88 |
mm/mm_init: simplify deferred_free_pages() migratetype init
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> |
||
|
|
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> |