[cgroup/for-6.20 PATCH 1/4] cgroup/cpuset: Streamline rm_siblings_excl_cpus()

Waiman Long posted 4 patches 1 month, 2 weeks ago
There is a newer version of this series
[cgroup/for-6.20 PATCH 1/4] cgroup/cpuset: Streamline rm_siblings_excl_cpus()
Posted by Waiman Long 1 month, 2 weeks ago
If exclusive_cpus is set, effective_xcpus must be a subset of
exclusive_cpus. Currently, rm_siblings_excl_cpus() checks both
exclusive_cpus and effective_xcpus connectively. It is simpler
to check only exclusive_cpus if non-empty or just effective_xcpus
otherwise.

No functional change is expected.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 kernel/cgroup/cpuset.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 221da921b4f9..3d2d28f0fd03 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1355,23 +1355,24 @@ static int rm_siblings_excl_cpus(struct cpuset *parent, struct cpuset *cs,
 	int retval = 0;
 
 	if (cpumask_empty(excpus))
-		return retval;
+		return 0;
 
 	/*
 	 * Exclude exclusive CPUs from siblings
 	 */
 	rcu_read_lock();
 	cpuset_for_each_child(sibling, css, parent) {
+		struct cpumask *sibling_xcpus;
+
 		if (sibling == cs)
 			continue;
 
-		if (cpumask_intersects(excpus, sibling->exclusive_cpus)) {
-			cpumask_andnot(excpus, excpus, sibling->exclusive_cpus);
-			retval++;
-			continue;
-		}
-		if (cpumask_intersects(excpus, sibling->effective_xcpus)) {
-			cpumask_andnot(excpus, excpus, sibling->effective_xcpus);
+		sibling_xcpus = cpumask_empty(sibling->exclusive_cpus)
+			      ? sibling->effective_xcpus
+			      : sibling->exclusive_cpus;
+
+		if (cpumask_intersects(excpus, sibling_xcpus)) {
+			cpumask_andnot(excpus, excpus, sibling_xcpus);
 			retval++;
 		}
 	}
-- 
2.52.0
Re: [cgroup/for-6.20 PATCH 1/4] cgroup/cpuset: Streamline rm_siblings_excl_cpus()
Posted by Chen Ridong 1 month, 2 weeks ago

On 2025/12/25 15:30, Waiman Long wrote:
> If exclusive_cpus is set, effective_xcpus must be a subset of
> exclusive_cpus. Currently, rm_siblings_excl_cpus() checks both
> exclusive_cpus and effective_xcpus connectively. It is simpler
> to check only exclusive_cpus if non-empty or just effective_xcpus
> otherwise.
> 
> No functional change is expected.
> 
> Signed-off-by: Waiman Long <longman@redhat.com>
> ---
>  kernel/cgroup/cpuset.c | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index 221da921b4f9..3d2d28f0fd03 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -1355,23 +1355,24 @@ static int rm_siblings_excl_cpus(struct cpuset *parent, struct cpuset *cs,
>  	int retval = 0;
>  
>  	if (cpumask_empty(excpus))
> -		return retval;
> +		return 0;
>  
>  	/*
>  	 * Exclude exclusive CPUs from siblings
>  	 */
>  	rcu_read_lock();
>  	cpuset_for_each_child(sibling, css, parent) {
> +		struct cpumask *sibling_xcpus;
> +
>  		if (sibling == cs)
>  			continue;
>  
> -		if (cpumask_intersects(excpus, sibling->exclusive_cpus)) {
> -			cpumask_andnot(excpus, excpus, sibling->exclusive_cpus);
> -			retval++;
> -			continue;
> -		}
> -		if (cpumask_intersects(excpus, sibling->effective_xcpus)) {
> -			cpumask_andnot(excpus, excpus, sibling->effective_xcpus);
> +		sibling_xcpus = cpumask_empty(sibling->exclusive_cpus)
> +			      ? sibling->effective_xcpus
> +			      : sibling->exclusive_cpus;
> +

I'm wondering if this is sufficient?

sibling_xcpus = sibling->effective_xcpus

      p(exclusive_cpus = 1)
   /	  \
 a	b(root, exclusive_cpus=1-7, effective_xcpus=1)

What the sibling's effective exclusive CPUs actually should be is not CPUs 1-7 but CPU 1. So, do we
need to remove CPUs 2-7?

> +		if (cpumask_intersects(excpus, sibling_xcpus)) {
> +			cpumask_andnot(excpus, excpus, sibling_xcpus);
>  			retval++;
>  		}
>  	}

-- 
Best regards,
Ridong
Re: [cgroup/for-6.20 PATCH 1/4] cgroup/cpuset: Streamline rm_siblings_excl_cpus()
Posted by Waiman Long 1 month, 1 week ago
On 12/25/25 4:27 AM, Chen Ridong wrote:
>
> On 2025/12/25 15:30, Waiman Long wrote:
>> If exclusive_cpus is set, effective_xcpus must be a subset of
>> exclusive_cpus. Currently, rm_siblings_excl_cpus() checks both
>> exclusive_cpus and effective_xcpus connectively. It is simpler
>> to check only exclusive_cpus if non-empty or just effective_xcpus
>> otherwise.
>>
>> No functional change is expected.
>>
>> Signed-off-by: Waiman Long <longman@redhat.com>
>> ---
>>   kernel/cgroup/cpuset.c | 17 +++++++++--------
>>   1 file changed, 9 insertions(+), 8 deletions(-)
>>
>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>> index 221da921b4f9..3d2d28f0fd03 100644
>> --- a/kernel/cgroup/cpuset.c
>> +++ b/kernel/cgroup/cpuset.c
>> @@ -1355,23 +1355,24 @@ static int rm_siblings_excl_cpus(struct cpuset *parent, struct cpuset *cs,
>>   	int retval = 0;
>>   
>>   	if (cpumask_empty(excpus))
>> -		return retval;
>> +		return 0;
>>   
>>   	/*
>>   	 * Exclude exclusive CPUs from siblings
>>   	 */
>>   	rcu_read_lock();
>>   	cpuset_for_each_child(sibling, css, parent) {
>> +		struct cpumask *sibling_xcpus;
>> +
>>   		if (sibling == cs)
>>   			continue;
>>   
>> -		if (cpumask_intersects(excpus, sibling->exclusive_cpus)) {
>> -			cpumask_andnot(excpus, excpus, sibling->exclusive_cpus);
>> -			retval++;
>> -			continue;
>> -		}
>> -		if (cpumask_intersects(excpus, sibling->effective_xcpus)) {
>> -			cpumask_andnot(excpus, excpus, sibling->effective_xcpus);
>> +		sibling_xcpus = cpumask_empty(sibling->exclusive_cpus)
>> +			      ? sibling->effective_xcpus
>> +			      : sibling->exclusive_cpus;
>> +
> I'm wondering if this is sufficient?
>
> sibling_xcpus = sibling->effective_xcpus
>
>        p(exclusive_cpus = 1)
>     /	  \
>   a	b(root, exclusive_cpus=1-7, effective_xcpus=1)
>
> What the sibling's effective exclusive CPUs actually should be is not CPUs 1-7 but CPU 1. So, do we
> need to remove CPUs 2-7?

By definition, exclusive_cpus have to be exclusive within the same child 
cpuset level even if some of the CPUs cannot be granted from the parent. 
So other siblings cannot use any of the CPUs 1-7 in its exclusive_cpus 
list or the writing will fail. In the case of cpuset.cpus defined 
partitions, those CPUs will be removed from its effective_xcpus list.

Cheers,
Longman
Re: [cgroup/for-6.20 PATCH 1/4] cgroup/cpuset: Streamline rm_siblings_excl_cpus()
Posted by Chen Ridong 1 month, 1 week ago

On 2025/12/27 15:40, Waiman Long wrote:
> On 12/25/25 4:27 AM, Chen Ridong wrote:
>>
>> On 2025/12/25 15:30, Waiman Long wrote:
>>> If exclusive_cpus is set, effective_xcpus must be a subset of
>>> exclusive_cpus. Currently, rm_siblings_excl_cpus() checks both
>>> exclusive_cpus and effective_xcpus connectively. It is simpler
>>> to check only exclusive_cpus if non-empty or just effective_xcpus
>>> otherwise.
>>>
>>> No functional change is expected.
>>>
>>> Signed-off-by: Waiman Long <longman@redhat.com>
>>> ---
>>>   kernel/cgroup/cpuset.c | 17 +++++++++--------
>>>   1 file changed, 9 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>>> index 221da921b4f9..3d2d28f0fd03 100644
>>> --- a/kernel/cgroup/cpuset.c
>>> +++ b/kernel/cgroup/cpuset.c
>>> @@ -1355,23 +1355,24 @@ static int rm_siblings_excl_cpus(struct cpuset *parent, struct cpuset *cs,
>>>       int retval = 0;
>>>         if (cpumask_empty(excpus))
>>> -        return retval;
>>> +        return 0;
>>>         /*
>>>        * Exclude exclusive CPUs from siblings
>>>        */
>>>       rcu_read_lock();
>>>       cpuset_for_each_child(sibling, css, parent) {
>>> +        struct cpumask *sibling_xcpus;
>>> +
>>>           if (sibling == cs)
>>>               continue;
>>>   -        if (cpumask_intersects(excpus, sibling->exclusive_cpus)) {
>>> -            cpumask_andnot(excpus, excpus, sibling->exclusive_cpus);
>>> -            retval++;
>>> -            continue;
>>> -        }
>>> -        if (cpumask_intersects(excpus, sibling->effective_xcpus)) {
>>> -            cpumask_andnot(excpus, excpus, sibling->effective_xcpus);
>>> +        sibling_xcpus = cpumask_empty(sibling->exclusive_cpus)
>>> +                  ? sibling->effective_xcpus
>>> +                  : sibling->exclusive_cpus;
>>> +
>> I'm wondering if this is sufficient?
>>
>> sibling_xcpus = sibling->effective_xcpus
>>
>>        p(exclusive_cpus = 1)
>>     /      \
>>   a    b(root, exclusive_cpus=1-7, effective_xcpus=1)
>>
>> What the sibling's effective exclusive CPUs actually should be is not CPUs 1-7 but CPU 1. So, do we
>> need to remove CPUs 2-7?
> 
> By definition, exclusive_cpus have to be exclusive within the same child cpuset level even if some
> of the CPUs cannot be granted from the parent. So other siblings cannot use any of the CPUs 1-7 in
> its exclusive_cpus list or the writing will fail. In the case of cpuset.cpus defined partitions,
> those CPUs will be removed from its effective_xcpus list.
> 
> Cheers,
> Longman
> 

Thank you for the clarification.

Looks good to me.

Reviewed-by: Chen Ridong <chenridong@huawei.com>

-- 
Best regards,
Ridong