cgroup/cpuset: Remove obsolete PFA_SPREAD_SLAB task flag

Commit 16a1d96835 ("mm/slab: remove mm/slab.c and slab_def.h")
removed the SLAB allocator, the only allocator that implemented cpuset
slab spreading. Commit 61a182ab61 ("cgroup/cpuset: Remove
cpuset_do_slab_mem_spread()") then removed the last task_spread_slab()
caller. Commit 3ab67a9ce8 ("cgroup/cpuset: Mark memory_spread_slab as
obsolete") marked the legacy control obsolete.

cpuset still updates PFA_SPREAD_SLAB when tasks attach to a legacy
cpuset and walks all tasks in a cpuset when memory_spread_slab changes.
Remove the unused task flag and its helpers, and make spread task
updates depend only on memory_spread_page.

Keep the memory_spread_slab control and CS_SPREAD_SLAB state so legacy
users retain the existing write, readback and inheritance behavior.
Update the comments and documentation to describe only page-cache
spreading as functional.

Assisted-by: LLM
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Guopeng Zhang
2026-08-11 15:43:08 -10:00
committed by Tejun Heo
parent 3345c7248a
commit 6dd5d93f6c
4 changed files with 27 additions and 52 deletions
+16 -26
View File
@@ -179,7 +179,7 @@ files describing that cpuset:
- cpuset.mem_hardwall flag: is memory allocation hardwalled
- cpuset.memory_pressure: measure of how much paging pressure in cpuset
- cpuset.memory_spread_page flag: if set, spread page cache evenly on allowed nodes
- cpuset.memory_spread_slab flag: OBSOLETE. Doesn't have any function.
- cpuset.memory_spread_slab flag: OBSOLETE. Has no effect on allocation behavior.
- cpuset.sched_load_balance flag: if set, load balance within CPUs on that cpuset
- cpuset.sched_relax_domain_level: the searching range when migrating tasks
@@ -318,26 +318,20 @@ times 1000.
1.6 What is memory spread ?
---------------------------
There are two boolean flag files per cpuset that control where the
kernel allocates pages for the file system buffers and related in
kernel data structures. They are called 'cpuset.memory_spread_page' and
'cpuset.memory_spread_slab'.
The 'cpuset.memory_spread_page' boolean flag file controls where the kernel
allocates page-cache pages.
The 'cpuset.memory_spread_slab' file is obsolete and has no effect on
allocation behavior, but is retained for compatibility.
If the per-cpuset boolean flag file 'cpuset.memory_spread_page' is set, then
the kernel will spread the file system buffers (page cache) evenly
over all the nodes that the faulting task is allowed to use, instead
of preferring to put those pages on the node where the task is running.
If the per-cpuset boolean flag file 'cpuset.memory_spread_slab' is set,
then the kernel will spread some file system related slab caches,
such as for inodes and dentries evenly over all the nodes that the
faulting task is allowed to use, instead of preferring to put those
pages on the node where the task is running.
The setting of these flags does not affect anonymous data segment or
The setting of this flag does not affect anonymous data segment or
stack segment pages of a task.
By default, both kinds of memory spreading are off, and memory
By default, page cache memory spreading is off, and memory
pages are allocated on the node local to where the task is running,
except perhaps as modified by the task's NUMA mempolicy or cpuset
configuration, so long as sufficient free memory pages are available.
@@ -345,18 +339,18 @@ configuration, so long as sufficient free memory pages are available.
When new cpusets are created, they inherit the memory spread settings
of their parent.
Setting memory spreading causes allocations for the affected page
or slab caches to ignore the task's NUMA mempolicy and be spread
instead. Tasks using mbind() or set_mempolicy() calls to set NUMA
mempolicies will not notice any change in these calls as a result of
their containing task's memory spread settings. If memory spreading
Setting page cache memory spreading causes affected allocations to ignore the
task's NUMA mempolicy and be spread instead. Tasks using mbind() or
set_mempolicy() to set NUMA mempolicies will not notice any change as a
result of their containing task's memory spread settings. If memory spreading
is turned off, then the currently specified NUMA mempolicy once again
applies to memory page allocations.
Both 'cpuset.memory_spread_page' and 'cpuset.memory_spread_slab' are boolean flag
files. By default they contain "0", meaning that the feature is off
for that cpuset. If a "1" is written to that file, then that turns
the named feature on.
Both 'cpuset.memory_spread_page' and 'cpuset.memory_spread_slab' are boolean
flag files. In the root cpuset, both files initially contain "0". Writing "1"
or "0" to 'cpuset.memory_spread_page' enables or disables page-cache spreading,
respectively. The value of 'cpuset.memory_spread_slab' is retained, can be read
back and inherited, but it does not affect allocation behavior.
The implementation is simple.
@@ -367,10 +361,6 @@ is modified to perform an inline check for this PFA_SPREAD_PAGE task
flag, and if set, a call to a new routine cpuset_mem_spread_node()
returns the node to prefer for the allocation.
Similarly, setting 'cpuset.memory_spread_slab' turns on the flag
PFA_SPREAD_SLAB, and appropriately marked slab caches will allocate
pages from the node returned by cpuset_mem_spread_node().
The cpuset_mem_spread_node() routine is also simple. It uses the
value of a per-task rotor cpuset_mem_spread_rotor to select the next
node in the current task's mems_allowed to prefer for the allocation.
-5
View File
@@ -1849,7 +1849,6 @@ static __always_inline bool is_user_task(struct task_struct *task)
/* Per-process atomic flags. */
#define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */
#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */
#define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */
#define PFA_SPEC_SSB_DISABLE 3 /* Speculative Store Bypass disabled */
#define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/
#define PFA_SPEC_IB_DISABLE 5 /* Indirect branch speculation restricted */
@@ -1875,10 +1874,6 @@ TASK_PFA_TEST(SPREAD_PAGE, spread_page)
TASK_PFA_SET(SPREAD_PAGE, spread_page)
TASK_PFA_CLEAR(SPREAD_PAGE, spread_page)
TASK_PFA_TEST(SPREAD_SLAB, spread_slab)
TASK_PFA_SET(SPREAD_SLAB, spread_slab)
TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab)
TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable)
TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable)
TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable)
+4 -9
View File
@@ -204,7 +204,7 @@ static s64 cpuset_read_s64(struct cgroup_subsys_state *css, struct cftype *cft)
}
/*
* update task's spread flag if cpuset's page/slab spread flag is set
* Update a task's spread flag if the cpuset's page spread flag is set.
*
* Call with callback_lock or cpuset_mutex held. The check can be skipped
* if on default hierarchy.
@@ -219,18 +219,13 @@ void cpuset1_update_task_spread_flags(struct cpuset *cs,
task_set_spread_page(tsk);
else
task_clear_spread_page(tsk);
if (is_spread_slab(cs))
task_set_spread_slab(tsk);
else
task_clear_spread_slab(tsk);
}
/**
* cpuset1_update_tasks_flags - update the spread flags of tasks in the cpuset.
* @cs: the cpuset in which each task's spread flags needs to be changed
* cpuset1_update_tasks_flags - update the page spread flag of cpuset tasks
* @cs: the cpuset whose tasks need their page spread flag updated
*
* Iterate through each task of @cs updating its spread flags. As this
* Iterate through each task of @cs updating its page spread flag. As this
* function is called with cpuset_mutex held, cpuset membership stays
* stable.
*/
+7 -12
View File
@@ -2859,7 +2859,7 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
{
struct cpuset *trialcs;
int balance_flag_changed;
int spread_flag_changed;
int spread_page_changed;
int err;
trialcs = dup_or_alloc_cpuset(cs);
@@ -2878,8 +2878,7 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
balance_flag_changed = (is_sched_load_balance(cs) !=
is_sched_load_balance(trialcs));
spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs))
|| (is_spread_page(cs) != is_spread_page(trialcs)));
spread_page_changed = is_spread_page(cs) != is_spread_page(trialcs);
spin_lock_irq(&callback_lock);
cs->flags = trialcs->flags;
@@ -2892,7 +2891,7 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
rebuild_sched_domains_locked();
}
if (spread_flag_changed)
if (spread_page_changed)
cpuset1_update_tasks_flags(cs);
out:
free_cpuset(trialcs);
@@ -4462,14 +4461,10 @@ void cpuset_nodes_allowed(struct cgroup *cgroup, nodemask_t *mask)
* cpuset_spread_node() - On which node to begin search for a page
* @rotor: round robin rotor
*
* If a task is marked PF_SPREAD_PAGE or PF_SPREAD_SLAB (as for
* tasks in a cpuset with is_spread_page or is_spread_slab set),
* and if the memory allocation used cpuset_mem_spread_node()
* to determine on which node to start looking, as it will for
* certain page cache or slab cache pages such as used for file
* system buffers and inode caches, then instead of starting on the
* local node to look for a free page, rather spread the starting
* node around the tasks mems_allowed nodes.
* If a task is marked PFA_SPREAD_PAGE and a page cache allocation uses
* cpuset_mem_spread_node() to determine where to start looking, spread the
* starting node around the task's mems_allowed nodes instead of starting on
* the local node.
*
* We don't have to worry about the returned node being offline
* because "it can't happen", and even if it did, it would be ok.