Linux cgroups development
 help / color / mirror / Atom feed
* [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update
@ 2026-05-27  6:43 Sun Shaojie
  2026-05-27  6:43 ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Sun Shaojie
  2026-05-27 19:05 ` [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Tejun Heo
  0 siblings, 2 replies; 6+ messages in thread
From: Sun Shaojie @ 2026-05-27  6:43 UTC (permalink / raw)
  To: Waiman Long, Chen Ridong, Tejun Heo, Johannes Weiner,
	Michal Koutný
  Cc: cgroups, linux-kernel, zhangguopeng, Sun Shaojie

Fix the partcmd_update path to use effective_xcpus instead of user_xcpus
for add/del mask calculation, and add test cases to verify the fix.

Changes in v2:
  - Updated comments to match the code change (suggested by Zhang Guopeng)
  - Added test cases for the fix

Sun Shaojie (2):
  cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask
    calculation
  cgroup/cpuset: Add test cases for sibling CPU exclusion on partition
    update

 kernel/cgroup/cpuset.c                            | 13 +++++++------
 tools/testing/selftests/cgroup/test_cpuset_prs.sh | 10 ++++++++++
 2 files changed, 17 insertions(+), 6 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation
  2026-05-27  6:43 [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Sun Shaojie
@ 2026-05-27  6:43 ` Sun Shaojie
  2026-05-27  7:05   ` [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update Sun Shaojie
  2026-05-27 18:01   ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Waiman Long
  2026-05-27 19:05 ` [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Tejun Heo
  1 sibling, 2 replies; 6+ messages in thread
From: Sun Shaojie @ 2026-05-27  6:43 UTC (permalink / raw)
  To: Waiman Long, Chen Ridong, Tejun Heo, Johannes Weiner,
	Michal Koutný
  Cc: cgroups, linux-kernel, zhangguopeng, Sun Shaojie

When sibling CPU exclusion occurs, a partition's user_xcpus may contain
CPUs that were never actually granted to it. These CPUs are present in
user_xcpus(cs) but not in cs->effective_xcpus.

The partcmd_update path in update_parent_effective_cpumask() uses
user_xcpus(cs) (via the local variable xcpus) to compute the addmask
(CPUs to return to parent) and delmask (CPUs to request from parent).
This is incorrect:

 1) When newmask removes a CPU that was previously excluded by a
    sibling, addmask incorrectly includes that CPU and tries to return
    it to the parent even though the partition never actually owned it,
    causing CPU overlap with sibling partitions and triggering warnings
    in generate_sched_domains().

 2) When newmask adds a previously excluded CPU that is now available,
    delmask fails to request it from the parent because user_xcpus(cs)
    already includes it.

Fix this by using cs->effective_xcpus instead of user_xcpus(cs) in all
partcmd_update paths that calculate addmask or delmask, including the
PERR_NOCPUS error handling paths.

Reproducers:

  Example 1 - Removing a sibling-excluded CPU incorrectly returns it:

    # cd /sys/fs/cgroup
    # echo "0-1" > a1/cpuset.cpus
    # echo "root" > a1/cpuset.cpus.partition
    # echo "0-2" > b1/cpuset.cpus
    # echo "root" > b1/cpuset.cpus.partition
    # echo "2" > b1/cpuset.cpus
    # cat cpuset.cpus.effective
    # Actual: 0-1,3    Expected: 3

  Example 2 - Expanding to a previously excluded CPU fails to request it:

    # cd /sys/fs/cgroup
    # echo "0-1" > a1/cpuset.cpus
    # echo "root" > a1/cpuset.cpus.partition
    # echo "0-2" > b1/cpuset.cpus
    # echo "root" > b1/cpuset.cpus.partition
    # echo "member" > a1/cpuset.cpus.partition
    # echo "1-2" > b1/cpuset.cpus
    # cat cpuset.cpus.effective
    # Actual: 0-1,3    Expected: 0,3

Fixes: 2a3602030d80 ("cgroup/cpuset: Don't invalidate sibling partitions on cpuset.cpus conflict")
Suggested-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
Signed-off-by: Sun Shaojie <sunshaojie@kylinos.cn>
---
 kernel/cgroup/cpuset.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 1335e437098e..2395c5aec871 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1807,9 +1807,9 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 		 * Compute add/delete mask to/from effective_cpus
 		 *
 		 * For valid partition:
-		 *   addmask = exclusive_cpus & ~newmask
+		 *   addmask = effective_xcpus & ~newmask
 		 *			      & parent->effective_xcpus
-		 *   delmask = newmask & ~exclusive_cpus
+		 *   delmask = newmask & ~effective_xcpus
 		 *		       & parent->effective_xcpus
 		 *
 		 * For invalid partition:
@@ -1821,11 +1821,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 			deleting = cpumask_and(tmp->delmask,
 					newmask, parent->effective_xcpus);
 		} else {
-			cpumask_andnot(tmp->addmask, xcpus, newmask);
+			cpumask_andnot(tmp->addmask, cs->effective_xcpus, newmask);
 			adding = cpumask_and(tmp->addmask, tmp->addmask,
 					     parent->effective_xcpus);
 
-			cpumask_andnot(tmp->delmask, newmask, xcpus);
+			cpumask_andnot(tmp->delmask, newmask, cs->effective_xcpus);
 			deleting = cpumask_and(tmp->delmask, tmp->delmask,
 					       parent->effective_xcpus);
 		}
@@ -1864,7 +1864,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 			part_error = PERR_NOCPUS;
 			deleting = false;
 			adding = cpumask_and(tmp->addmask,
-					     xcpus, parent->effective_xcpus);
+					     cs->effective_xcpus, parent->effective_xcpus);
 		}
 	} else {
 		/*
@@ -1886,7 +1886,8 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 			part_error = PERR_NOCPUS;
 			if (is_partition_valid(cs))
 				adding = cpumask_and(tmp->addmask,
-						xcpus, parent->effective_xcpus);
+						     cs->effective_xcpus,
+						     parent->effective_xcpus);
 		} else if (is_partition_invalid(cs) && !cpumask_empty(xcpus) &&
 			   cpumask_subset(xcpus, parent->effective_xcpus)) {
 			struct cgroup_subsys_state *css;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update
  2026-05-27  6:43 ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Sun Shaojie
@ 2026-05-27  7:05   ` Sun Shaojie
  2026-05-27 18:08     ` Waiman Long
  2026-05-27 18:01   ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Waiman Long
  1 sibling, 1 reply; 6+ messages in thread
From: Sun Shaojie @ 2026-05-27  7:05 UTC (permalink / raw)
  To: Waiman Long, Chen Ridong, Tejun Heo, Johannes Weiner,
	Michal Koutný
  Cc: cgroups, linux-kernel, zhangguopeng, Sun Shaojie

When sibling CPU exclusion occurs, a partition's effective_xcpus may be
a subset of its user_xcpus. The partcmd_update path must use
effective_xcpus instead of user_xcpus when calculating CPUs to return
to or request from the parent.

Add two test cases to verify this behavior:

  1) Narrowing cpuset.cpus to only the sibling-excluded CPUs should not
     return CPUs to parent that the partition never actually owned.

  2) Expanding cpuset.cpus after a sibling becomes a member should
     correctly request the additional CPUs from parent.

Co-developed-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
Signed-off-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
Signed-off-by: Sun Shaojie <sunshaojie@kylinos.cn>
---
 tools/testing/selftests/cgroup/test_cpuset_prs.sh | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index a56f4153c64d..683b05062810 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -492,6 +492,16 @@ REMOTE_TEST_MATRIX=(
 	"  C1-5:P1   .  C1-4:P1   C2-3     .       .  \
 	      .      .     .       P1      .       .     p1:5|c11:1-4|c12:5 \
 							 p1:P1|c11:P1|c12:P-1"
+	# Narrowing cpuset.cpus to previously sibling-excluded CPUs should
+	# not return CPUs that were never actually owned.
+	"  C1-4:P1   .   C1-2:P1  C1-3:P2  .       .  \
+	      .      .     .         C3    .       .     p1:4|c11:1-2|c12:3 \
+							 p1:P1|c11:P1|c12:P2 3"
+	# Expanding cpuset.cpus to include a previously sibling-excluded CPU
+	# after the sibling has become a member should correctly request it.
+	"  C1-4:P1   .   C1-2:P1  C1-3:P2  .       .  \
+	      .      .      P0     C2-3    .       .     p1:1,4|c11:1|c12:2-3 \
+							 p1:P1|c11:P0|c12:P2 2-3"
 )
 
 #
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation
  2026-05-27  6:43 ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Sun Shaojie
  2026-05-27  7:05   ` [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update Sun Shaojie
@ 2026-05-27 18:01   ` Waiman Long
  1 sibling, 0 replies; 6+ messages in thread
From: Waiman Long @ 2026-05-27 18:01 UTC (permalink / raw)
  To: Sun Shaojie, Chen Ridong, Tejun Heo, Johannes Weiner,
	Michal Koutný
  Cc: cgroups, linux-kernel, zhangguopeng

On 5/27/26 2:43 AM, Sun Shaojie wrote:
> When sibling CPU exclusion occurs, a partition's user_xcpus may contain
> CPUs that were never actually granted to it. These CPUs are present in
> user_xcpus(cs) but not in cs->effective_xcpus.
>
> The partcmd_update path in update_parent_effective_cpumask() uses
> user_xcpus(cs) (via the local variable xcpus) to compute the addmask
> (CPUs to return to parent) and delmask (CPUs to request from parent).
> This is incorrect:
>
>   1) When newmask removes a CPU that was previously excluded by a
>      sibling, addmask incorrectly includes that CPU and tries to return
>      it to the parent even though the partition never actually owned it,
>      causing CPU overlap with sibling partitions and triggering warnings
>      in generate_sched_domains().
>
>   2) When newmask adds a previously excluded CPU that is now available,
>      delmask fails to request it from the parent because user_xcpus(cs)
>      already includes it.
>
> Fix this by using cs->effective_xcpus instead of user_xcpus(cs) in all
> partcmd_update paths that calculate addmask or delmask, including the
> PERR_NOCPUS error handling paths.
>
> Reproducers:
>
>    Example 1 - Removing a sibling-excluded CPU incorrectly returns it:
>
>      # cd /sys/fs/cgroup
>      # echo "0-1" > a1/cpuset.cpus
>      # echo "root" > a1/cpuset.cpus.partition
>      # echo "0-2" > b1/cpuset.cpus
>      # echo "root" > b1/cpuset.cpus.partition
>      # echo "2" > b1/cpuset.cpus
>      # cat cpuset.cpus.effective
>      # Actual: 0-1,3    Expected: 3
>
>    Example 2 - Expanding to a previously excluded CPU fails to request it:
>
>      # cd /sys/fs/cgroup
>      # echo "0-1" > a1/cpuset.cpus
>      # echo "root" > a1/cpuset.cpus.partition
>      # echo "0-2" > b1/cpuset.cpus
>      # echo "root" > b1/cpuset.cpus.partition
>      # echo "member" > a1/cpuset.cpus.partition
>      # echo "1-2" > b1/cpuset.cpus
>      # cat cpuset.cpus.effective
>      # Actual: 0-1,3    Expected: 0,3
>
> Fixes: 2a3602030d80 ("cgroup/cpuset: Don't invalidate sibling partitions on cpuset.cpus conflict")
> Suggested-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
> Signed-off-by: Sun Shaojie <sunshaojie@kylinos.cn>
> ---
>   kernel/cgroup/cpuset.c | 13 +++++++------
>   1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index 1335e437098e..2395c5aec871 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -1807,9 +1807,9 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
>   		 * Compute add/delete mask to/from effective_cpus
>   		 *
>   		 * For valid partition:
> -		 *   addmask = exclusive_cpus & ~newmask
> +		 *   addmask = effective_xcpus & ~newmask
>   		 *			      & parent->effective_xcpus
> -		 *   delmask = newmask & ~exclusive_cpus
> +		 *   delmask = newmask & ~effective_xcpus
>   		 *		       & parent->effective_xcpus
>   		 *
>   		 * For invalid partition:
> @@ -1821,11 +1821,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
>   			deleting = cpumask_and(tmp->delmask,
>   					newmask, parent->effective_xcpus);
>   		} else {
> -			cpumask_andnot(tmp->addmask, xcpus, newmask);
> +			cpumask_andnot(tmp->addmask, cs->effective_xcpus, newmask);
>   			adding = cpumask_and(tmp->addmask, tmp->addmask,
>   					     parent->effective_xcpus);
>   
> -			cpumask_andnot(tmp->delmask, newmask, xcpus);
> +			cpumask_andnot(tmp->delmask, newmask, cs->effective_xcpus);
>   			deleting = cpumask_and(tmp->delmask, tmp->delmask,
>   					       parent->effective_xcpus);
>   		}
> @@ -1864,7 +1864,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
>   			part_error = PERR_NOCPUS;
>   			deleting = false;
>   			adding = cpumask_and(tmp->addmask,
> -					     xcpus, parent->effective_xcpus);
> +					     cs->effective_xcpus, parent->effective_xcpus);
>   		}
>   	} else {
>   		/*
> @@ -1886,7 +1886,8 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
>   			part_error = PERR_NOCPUS;
>   			if (is_partition_valid(cs))
>   				adding = cpumask_and(tmp->addmask,
> -						xcpus, parent->effective_xcpus);
> +						     cs->effective_xcpus,
> +						     parent->effective_xcpus);
>   		} else if (is_partition_invalid(cs) && !cpumask_empty(xcpus) &&
>   			   cpumask_subset(xcpus, parent->effective_xcpus)) {
>   			struct cgroup_subsys_state *css;
Reviewed-by: Waiman Long <longman@redhat.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update
  2026-05-27  7:05   ` [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update Sun Shaojie
@ 2026-05-27 18:08     ` Waiman Long
  0 siblings, 0 replies; 6+ messages in thread
From: Waiman Long @ 2026-05-27 18:08 UTC (permalink / raw)
  To: Sun Shaojie, Chen Ridong, Tejun Heo, Johannes Weiner,
	Michal Koutný
  Cc: cgroups, linux-kernel, zhangguopeng

On 5/27/26 3:05 AM, Sun Shaojie wrote:
> When sibling CPU exclusion occurs, a partition's effective_xcpus may be
> a subset of its user_xcpus. The partcmd_update path must use
> effective_xcpus instead of user_xcpus when calculating CPUs to return
> to or request from the parent.
>
> Add two test cases to verify this behavior:
>
>    1) Narrowing cpuset.cpus to only the sibling-excluded CPUs should not
>       return CPUs to parent that the partition never actually owned.
>
>    2) Expanding cpuset.cpus after a sibling becomes a member should
>       correctly request the additional CPUs from parent.
>
> Co-developed-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
> Signed-off-by: Zhang Guopeng <zhangguopeng@kylinos.cn>
> Signed-off-by: Sun Shaojie <sunshaojie@kylinos.cn>
> ---
>   tools/testing/selftests/cgroup/test_cpuset_prs.sh | 10 ++++++++++
>   1 file changed, 10 insertions(+)
>
> diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> index a56f4153c64d..683b05062810 100755
> --- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> +++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
> @@ -492,6 +492,16 @@ REMOTE_TEST_MATRIX=(
>   	"  C1-5:P1   .  C1-4:P1   C2-3     .       .  \
>   	      .      .     .       P1      .       .     p1:5|c11:1-4|c12:5 \
>   							 p1:P1|c11:P1|c12:P-1"
> +	# Narrowing cpuset.cpus to previously sibling-excluded CPUs should
> +	# not return CPUs that were never actually owned.
> +	"  C1-4:P1   .   C1-2:P1  C1-3:P2  .       .  \
> +	      .      .     .         C3    .       .     p1:4|c11:1-2|c12:3 \
> +							 p1:P1|c11:P1|c12:P2 3"
> +	# Expanding cpuset.cpus to include a previously sibling-excluded CPU
> +	# after the sibling has become a member should correctly request it.
> +	"  C1-4:P1   .   C1-2:P1  C1-3:P2  .       .  \
> +	      .      .      P0     C2-3    .       .     p1:1,4|c11:1|c12:2-3 \
> +							 p1:P1|c11:P0|c12:P2 2-3"
>   )
>   
>   #
Reviewed-by: Waiman Long <longman@redhat.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update
  2026-05-27  6:43 [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Sun Shaojie
  2026-05-27  6:43 ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Sun Shaojie
@ 2026-05-27 19:05 ` Tejun Heo
  1 sibling, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2026-05-27 19:05 UTC (permalink / raw)
  To: Sun Shaojie
  Cc: Waiman Long, Chen Ridong, Johannes Weiner, Michal Koutný,
	cgroups, linux-kernel, zhangguopeng

Hello,

On Wed, May 27, 2026 at 02:43:27PM +0800, Sun Shaojie wrote:
> Sun Shaojie (2):
>   cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask
>     calculation
>   cgroup/cpuset: Add test cases for sibling CPU exclusion on partition
>     update

Applied to cgroup/for-7.1-fixes with the following changes:

- Added Cc: stable@vger.kernel.org # v7.0+ to the fix since 2a3602030d80
  shipped in v7.0.
- Added Reviewed-by: Waiman Long <longman@redhat.com> to both patches.

Thanks.

--
tejun

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-05-27 19:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27  6:43 [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Sun Shaojie
2026-05-27  6:43 ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Sun Shaojie
2026-05-27  7:05   ` [PATCH v2 2/2] cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update Sun Shaojie
2026-05-27 18:08     ` Waiman Long
2026-05-27 18:01   ` [PATCH v2 1/2] cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation Waiman Long
2026-05-27 19:05 ` [PATCH v2 0/2] cgroup/cpuset: Fix sibling CPU exclusion in partcmd_update Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox