Skip to content

Commit 272bd81

Browse files
Waiman-Longhtejun
authored andcommitted
cgroup/cpuset: Move the v1 empty cpus/mems check to cpuset1_validate_change()
As stated in commit 1c09b19 ("cpuset: fix a regression in validating config change"), it is not allowed to clear masks of a cpuset if there're tasks in it. This is specific to v1 since empty "cpuset.cpus" or "cpuset.mems" will cause the v2 cpuset to inherit the effective CPUs or memory nodes from its parent. So it is OK to have empty cpus or mems even if there are tasks in the cpuset. Move this empty cpus/mems check in validate_change() to cpuset1_validate_change() to allow more flexibility in setting cpus or mems in v2. cpuset_is_populated() needs to be moved into cpuset-internal.h as it is needed by the empty cpus/mems checking code. Also add a test case to test_cpuset_prs.sh to verify that. Reported-by: Chen Ridong <[email protected]> Closes: https://lore.kernel.org/lkml/[email protected]/ Signed-off-by: Waiman Long <[email protected]> Reviewed-by: Chen Ridong <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 2a36020 commit 272bd81

4 files changed

Lines changed: 26 additions & 23 deletions

File tree

kernel/cgroup/cpuset-internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,15 @@ static inline int nr_cpusets(void)
260260
return static_key_count(&cpusets_enabled_key.key) + 1;
261261
}
262262

263+
static inline bool cpuset_is_populated(struct cpuset *cs)
264+
{
265+
lockdep_assert_cpuset_lock_held();
266+
267+
/* Cpusets in the process of attaching should be considered as populated */
268+
return cgroup_is_populated(cs->css.cgroup) ||
269+
cs->attach_in_progress;
270+
}
271+
263272
/**
264273
* cpuset_for_each_child - traverse online children of a cpuset
265274
* @child_cs: loop cursor pointing to the current child

kernel/cgroup/cpuset-v1.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,20 @@ int cpuset1_validate_change(struct cpuset *cur, struct cpuset *trial)
368368
if (par && !is_cpuset_subset(trial, par))
369369
goto out;
370370

371+
/*
372+
* Cpusets with tasks - existing or newly being attached - can't
373+
* be changed to have empty cpus_allowed or mems_allowed.
374+
*/
375+
ret = -ENOSPC;
376+
if (cpuset_is_populated(cur)) {
377+
if (!cpumask_empty(cur->cpus_allowed) &&
378+
cpumask_empty(trial->cpus_allowed))
379+
goto out;
380+
if (!nodes_empty(cur->mems_allowed) &&
381+
nodes_empty(trial->mems_allowed))
382+
goto out;
383+
}
384+
371385
ret = 0;
372386
out:
373387
return ret;

kernel/cgroup/cpuset.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -370,15 +370,6 @@ static inline bool is_in_v2_mode(void)
370370
(cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE);
371371
}
372372

373-
static inline bool cpuset_is_populated(struct cpuset *cs)
374-
{
375-
lockdep_assert_held(&cpuset_mutex);
376-
377-
/* Cpusets in the process of attaching should be considered as populated */
378-
return cgroup_is_populated(cs->css.cgroup) ||
379-
cs->attach_in_progress;
380-
}
381-
382373
/**
383374
* partition_is_populated - check if partition has tasks
384375
* @cs: partition root to be checked
@@ -695,20 +686,6 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
695686

696687
par = parent_cs(cur);
697688

698-
/*
699-
* Cpusets with tasks - existing or newly being attached - can't
700-
* be changed to have empty cpus_allowed or mems_allowed.
701-
*/
702-
ret = -ENOSPC;
703-
if (cpuset_is_populated(cur)) {
704-
if (!cpumask_empty(cur->cpus_allowed) &&
705-
cpumask_empty(trial->cpus_allowed))
706-
goto out;
707-
if (!nodes_empty(cur->mems_allowed) &&
708-
nodes_empty(trial->mems_allowed))
709-
goto out;
710-
}
711-
712689
/*
713690
* We can't shrink if we won't have enough room for SCHED_DEADLINE
714691
* tasks. This check is not done when scheduling is disabled as the

tools/testing/selftests/cgroup/test_cpuset_prs.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ TEST_MATRIX=(
425425
# cpuset.cpus can be set to a subset of sibling's cpuset.cpus.exclusive
426426
" C1-3:X1-3 . . C4-5 . . . C1-2 0 A1:1-3|B1:1-2"
427427
428+
# cpuset.cpus can become empty with task in it as it inherits parent's effective CPUs
429+
" C1-3:S+ C2 . . . T:C . . 0 A1:1-3|A2:1-3"
430+
428431
# old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS
429432
# ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ --------
430433
# Failure cases:

0 commit comments

Comments
 (0)