Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cgroup/cpuset: Move the v1 empty cpus/mems check to cpuset1_validate_change()

As stated in commit 1c09b195d37f ("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 <chenridong@huaweicloud.com>
Closes: https://lore.kernel.org/lkml/7a3ec392-2e86-4693-aa9f-1e668a668b9c@huaweicloud.com/
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Chen Ridong <chenridong@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Waiman Long and committed by
Tejun Heo
272bd818 2a360203

+26 -23
+9
kernel/cgroup/cpuset-internal.h
··· 260 260 return static_key_count(&cpusets_enabled_key.key) + 1; 261 261 } 262 262 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 + 263 272 /** 264 273 * cpuset_for_each_child - traverse online children of a cpuset 265 274 * @child_cs: loop cursor pointing to the current child
+14
kernel/cgroup/cpuset-v1.c
··· 368 368 if (par && !is_cpuset_subset(trial, par)) 369 369 goto out; 370 370 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 + 371 385 ret = 0; 372 386 out: 373 387 return ret;
-23
kernel/cgroup/cpuset.c
··· 370 370 (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); 371 371 } 372 372 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 - 382 373 /** 383 374 * partition_is_populated - check if partition has tasks 384 375 * @cs: partition root to be checked ··· 685 694 goto out; 686 695 687 696 par = parent_cs(cur); 688 - 689 - /* 690 - * Cpusets with tasks - existing or newly being attached - can't 691 - * be changed to have empty cpus_allowed or mems_allowed. 692 - */ 693 - ret = -ENOSPC; 694 - if (cpuset_is_populated(cur)) { 695 - if (!cpumask_empty(cur->cpus_allowed) && 696 - cpumask_empty(trial->cpus_allowed)) 697 - goto out; 698 - if (!nodes_empty(cur->mems_allowed) && 699 - nodes_empty(trial->mems_allowed)) 700 - goto out; 701 - } 702 697 703 698 /* 704 699 * We can't shrink if we won't have enough room for SCHED_DEADLINE
+3
tools/testing/selftests/cgroup/test_cpuset_prs.sh
··· 425 425 # cpuset.cpus can be set to a subset of sibling's cpuset.cpus.exclusive 426 426 " C1-3:X1-3 . . C4-5 . . . C1-2 0 A1:1-3|B1:1-2" 427 427 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 + 428 431 # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS 429 432 # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- 430 433 # Failure cases: