* [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-08 9:25 [PATCH -next 0/4] some optimization for cpuset Chen Ridong
@ 2025-08-08 9:25 ` Chen Ridong
2025-08-12 14:44 ` Waiman Long
2025-08-08 9:25 ` [PATCH -next 2/4] cpuset: add helpers for cpuset related locks Chen Ridong
` (2 subsequent siblings)
3 siblings, 1 reply; 14+ messages in thread
From: Chen Ridong @ 2025-08-08 9:25 UTC (permalink / raw)
To: tj, hannes, mkoutny, longman, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
From: Chen Ridong <chenridong@huawei.com>
The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
cpuset subsystem. Currently, the flag setting sequence is as follows:
1. cpuset_css_online() sets CS_ONLINE
2. css->flags gets CSS_ONLINE set
...
3. cgroup->kill_css sets CSS_DYING
4. cpuset_css_offline() clears CS_ONLINE
5. css->flags clears CSS_ONLINE
The is_cpuset_online() check currently occurs between steps 1 and 3.
However, it would be equally safe to perform this check between steps 2
and 3, as CSS_ONLINE provides the same synchronization guarantee as
CS_ONLINE.
Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
synchronization benefits, we can safely remove it to simplify the code.
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
include/linux/cgroup.h | 5 +++++
kernel/cgroup/cpuset-internal.h | 3 +--
kernel/cgroup/cpuset.c | 4 +---
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b18fb5fcb38e..ae73dbb19165 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
return css->flags & CSS_DYING;
}
+static inline bool css_is_online(struct cgroup_subsys_state *css)
+{
+ return css->flags & CSS_ONLINE;
+}
+
static inline bool css_is_self(struct cgroup_subsys_state *css)
{
if (css == &css->cgroup->self) {
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
index 383963e28ac6..75b3aef39231 100644
--- a/kernel/cgroup/cpuset-internal.h
+++ b/kernel/cgroup/cpuset-internal.h
@@ -38,7 +38,6 @@ enum prs_errcode {
/* bits in struct cpuset flags field */
typedef enum {
- CS_ONLINE,
CS_CPU_EXCLUSIVE,
CS_MEM_EXCLUSIVE,
CS_MEM_HARDWALL,
@@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
/* convenient tests for these bits */
static inline bool is_cpuset_online(struct cpuset *cs)
{
- return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
+ return css_is_online(&cs->css) && !css_is_dying(&cs->css);
}
static inline int is_cpu_exclusive(const struct cpuset *cs)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index f74d04429a29..cf7cd2255265 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
* parallel, we may leave an offline CPU in cpu_allowed or some other masks.
*/
static struct cpuset top_cpuset = {
- .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
+ .flags = BIT(CS_CPU_EXCLUSIVE) |
BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
.partition_root_state = PRS_ROOT,
.relax_domain_level = -1,
@@ -3498,7 +3498,6 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
cpus_read_lock();
mutex_lock(&cpuset_mutex);
- set_bit(CS_ONLINE, &cs->flags);
if (is_spread_page(parent))
set_bit(CS_SPREAD_PAGE, &cs->flags);
if (is_spread_slab(parent))
@@ -3573,7 +3572,6 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
cpuset_dec();
- clear_bit(CS_ONLINE, &cs->flags);
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-08 9:25 ` [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag Chen Ridong
@ 2025-08-12 14:44 ` Waiman Long
2025-08-13 0:54 ` Chen Ridong
0 siblings, 1 reply; 14+ messages in thread
From: Waiman Long @ 2025-08-12 14:44 UTC (permalink / raw)
To: Chen Ridong, tj, hannes, mkoutny, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 8/8/25 5:25 AM, Chen Ridong wrote:
> From: Chen Ridong <chenridong@huawei.com>
>
> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
> cpuset subsystem. Currently, the flag setting sequence is as follows:
>
> 1. cpuset_css_online() sets CS_ONLINE
> 2. css->flags gets CSS_ONLINE set
> ...
> 3. cgroup->kill_css sets CSS_DYING
> 4. cpuset_css_offline() clears CS_ONLINE
> 5. css->flags clears CSS_ONLINE
>
> The is_cpuset_online() check currently occurs between steps 1 and 3.
> However, it would be equally safe to perform this check between steps 2
> and 3, as CSS_ONLINE provides the same synchronization guarantee as
> CS_ONLINE.
>
> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
> synchronization benefits, we can safely remove it to simplify the code.
>
> Signed-off-by: Chen Ridong <chenridong@huawei.com>
> ---
> include/linux/cgroup.h | 5 +++++
> kernel/cgroup/cpuset-internal.h | 3 +--
> kernel/cgroup/cpuset.c | 4 +---
> 3 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index b18fb5fcb38e..ae73dbb19165 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
> return css->flags & CSS_DYING;
> }
>
> +static inline bool css_is_online(struct cgroup_subsys_state *css)
> +{
> + return css->flags & CSS_ONLINE;
> +}
> +
> static inline bool css_is_self(struct cgroup_subsys_state *css)
> {
> if (css == &css->cgroup->self) {
> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
> index 383963e28ac6..75b3aef39231 100644
> --- a/kernel/cgroup/cpuset-internal.h
> +++ b/kernel/cgroup/cpuset-internal.h
> @@ -38,7 +38,6 @@ enum prs_errcode {
>
> /* bits in struct cpuset flags field */
> typedef enum {
> - CS_ONLINE,
> CS_CPU_EXCLUSIVE,
> CS_MEM_EXCLUSIVE,
> CS_MEM_HARDWALL,
> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
> /* convenient tests for these bits */
> static inline bool is_cpuset_online(struct cpuset *cs)
> {
> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
> }
>
> static inline int is_cpu_exclusive(const struct cpuset *cs)
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index f74d04429a29..cf7cd2255265 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
> */
> static struct cpuset top_cpuset = {
> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
> + .flags = BIT(CS_CPU_EXCLUSIVE) |
> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
> .partition_root_state = PRS_ROOT,
> .relax_domain_level = -1,
top_cpuset.css is not initialized like the one in the children. If you
modify is_cpuset_online() to test the css.flags, you will probably need
to set the CSS_ONLINE flag in top_cpuset.css.flags. I do doubt that we
will apply the is_cpuset_online() test on top_cpuset. To be consistent,
we should support that.
BTW, other statically allocated css'es in the cgroup root may have
similar problem. If you make the css_is_online() helper available to all
other controllers, you will have to document that limitation.
Cheers,
Longman
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-12 14:44 ` Waiman Long
@ 2025-08-13 0:54 ` Chen Ridong
2025-08-13 1:00 ` Waiman Long
0 siblings, 1 reply; 14+ messages in thread
From: Chen Ridong @ 2025-08-13 0:54 UTC (permalink / raw)
To: Waiman Long, tj, hannes, mkoutny, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 2025/8/12 22:44, Waiman Long wrote:
> On 8/8/25 5:25 AM, Chen Ridong wrote:
>> From: Chen Ridong <chenridong@huawei.com>
>>
>> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
>> cpuset subsystem. Currently, the flag setting sequence is as follows:
>>
>> 1. cpuset_css_online() sets CS_ONLINE
>> 2. css->flags gets CSS_ONLINE set
>> ...
>> 3. cgroup->kill_css sets CSS_DYING
>> 4. cpuset_css_offline() clears CS_ONLINE
>> 5. css->flags clears CSS_ONLINE
>>
>> The is_cpuset_online() check currently occurs between steps 1 and 3.
>> However, it would be equally safe to perform this check between steps 2
>> and 3, as CSS_ONLINE provides the same synchronization guarantee as
>> CS_ONLINE.
>>
>> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
>> synchronization benefits, we can safely remove it to simplify the code.
>>
>> Signed-off-by: Chen Ridong <chenridong@huawei.com>
>> ---
>> include/linux/cgroup.h | 5 +++++
>> kernel/cgroup/cpuset-internal.h | 3 +--
>> kernel/cgroup/cpuset.c | 4 +---
>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>> index b18fb5fcb38e..ae73dbb19165 100644
>> --- a/include/linux/cgroup.h
>> +++ b/include/linux/cgroup.h
>> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
>> return css->flags & CSS_DYING;
>> }
>> +static inline bool css_is_online(struct cgroup_subsys_state *css)
>> +{
>> + return css->flags & CSS_ONLINE;
>> +}
>> +
>> static inline bool css_is_self(struct cgroup_subsys_state *css)
>> {
>> if (css == &css->cgroup->self) {
>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>> index 383963e28ac6..75b3aef39231 100644
>> --- a/kernel/cgroup/cpuset-internal.h
>> +++ b/kernel/cgroup/cpuset-internal.h
>> @@ -38,7 +38,6 @@ enum prs_errcode {
>> /* bits in struct cpuset flags field */
>> typedef enum {
>> - CS_ONLINE,
>> CS_CPU_EXCLUSIVE,
>> CS_MEM_EXCLUSIVE,
>> CS_MEM_HARDWALL,
>> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
>> /* convenient tests for these bits */
>> static inline bool is_cpuset_online(struct cpuset *cs)
>> {
>> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
>> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
>> }
>> static inline int is_cpu_exclusive(const struct cpuset *cs)
>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>> index f74d04429a29..cf7cd2255265 100644
>> --- a/kernel/cgroup/cpuset.c
>> +++ b/kernel/cgroup/cpuset.c
>> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
>> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
>> */
>> static struct cpuset top_cpuset = {
>> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
>> + .flags = BIT(CS_CPU_EXCLUSIVE) |
>> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
>> .partition_root_state = PRS_ROOT,
>> .relax_domain_level = -1,
>
> top_cpuset.css is not initialized like the one in the children. If you modify is_cpuset_online() to
> test the css.flags, you will probably need to set the CSS_ONLINE flag in top_cpuset.css.flags. I do
> doubt that we will apply the is_cpuset_online() test on top_cpuset. To be consistent, we should
> support that.
>
> BTW, other statically allocated css'es in the cgroup root may have similar problem. If you make the
> css_is_online() helper available to all other controllers, you will have to document that limitation.
>
> Cheers,
> Longman
Hi, Longman, thank you for your response.
If I understand correctly, the CSS_ONLINE flag should be set in top_cpuset.css during the following
process:
css_create
css = ss->css_alloc(parent_css); // cgroup root is static, unlike children
online_css(css);
ret = ss->css_online(css); // css root may differ from children
css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
I think css online must be successful, and it's CSS_ONLINE flag must be set. Do I missing anything?
Best regards,
Ridong
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-13 0:54 ` Chen Ridong
@ 2025-08-13 1:00 ` Waiman Long
2025-08-13 1:20 ` Chen Ridong
0 siblings, 1 reply; 14+ messages in thread
From: Waiman Long @ 2025-08-13 1:00 UTC (permalink / raw)
To: Chen Ridong, Waiman Long, tj, hannes, mkoutny, mingo, peterz,
juri.lelli, vincent.guittot, dietmar.eggemann, rostedt, bsegall,
mgorman, vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 8/12/25 8:54 PM, Chen Ridong wrote:
>
> On 2025/8/12 22:44, Waiman Long wrote:
>> On 8/8/25 5:25 AM, Chen Ridong wrote:
>>> From: Chen Ridong <chenridong@huawei.com>
>>>
>>> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
>>> cpuset subsystem. Currently, the flag setting sequence is as follows:
>>>
>>> 1. cpuset_css_online() sets CS_ONLINE
>>> 2. css->flags gets CSS_ONLINE set
>>> ...
>>> 3. cgroup->kill_css sets CSS_DYING
>>> 4. cpuset_css_offline() clears CS_ONLINE
>>> 5. css->flags clears CSS_ONLINE
>>>
>>> The is_cpuset_online() check currently occurs between steps 1 and 3.
>>> However, it would be equally safe to perform this check between steps 2
>>> and 3, as CSS_ONLINE provides the same synchronization guarantee as
>>> CS_ONLINE.
>>>
>>> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
>>> synchronization benefits, we can safely remove it to simplify the code.
>>>
>>> Signed-off-by: Chen Ridong <chenridong@huawei.com>
>>> ---
>>> include/linux/cgroup.h | 5 +++++
>>> kernel/cgroup/cpuset-internal.h | 3 +--
>>> kernel/cgroup/cpuset.c | 4 +---
>>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>>> index b18fb5fcb38e..ae73dbb19165 100644
>>> --- a/include/linux/cgroup.h
>>> +++ b/include/linux/cgroup.h
>>> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
>>> return css->flags & CSS_DYING;
>>> }
>>> +static inline bool css_is_online(struct cgroup_subsys_state *css)
>>> +{
>>> + return css->flags & CSS_ONLINE;
>>> +}
>>> +
>>> static inline bool css_is_self(struct cgroup_subsys_state *css)
>>> {
>>> if (css == &css->cgroup->self) {
>>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>>> index 383963e28ac6..75b3aef39231 100644
>>> --- a/kernel/cgroup/cpuset-internal.h
>>> +++ b/kernel/cgroup/cpuset-internal.h
>>> @@ -38,7 +38,6 @@ enum prs_errcode {
>>> /* bits in struct cpuset flags field */
>>> typedef enum {
>>> - CS_ONLINE,
>>> CS_CPU_EXCLUSIVE,
>>> CS_MEM_EXCLUSIVE,
>>> CS_MEM_HARDWALL,
>>> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
>>> /* convenient tests for these bits */
>>> static inline bool is_cpuset_online(struct cpuset *cs)
>>> {
>>> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
>>> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
>>> }
>>> static inline int is_cpu_exclusive(const struct cpuset *cs)
>>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>>> index f74d04429a29..cf7cd2255265 100644
>>> --- a/kernel/cgroup/cpuset.c
>>> +++ b/kernel/cgroup/cpuset.c
>>> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
>>> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
>>> */
>>> static struct cpuset top_cpuset = {
>>> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
>>> + .flags = BIT(CS_CPU_EXCLUSIVE) |
>>> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
>>> .partition_root_state = PRS_ROOT,
>>> .relax_domain_level = -1,
>> top_cpuset.css is not initialized like the one in the children. If you modify is_cpuset_online() to
>> test the css.flags, you will probably need to set the CSS_ONLINE flag in top_cpuset.css.flags. I do
>> doubt that we will apply the is_cpuset_online() test on top_cpuset. To be consistent, we should
>> support that.
>>
>> BTW, other statically allocated css'es in the cgroup root may have similar problem. If you make the
>> css_is_online() helper available to all other controllers, you will have to document that limitation.
>>
>> Cheers,
>> Longman
> Hi, Longman, thank you for your response.
>
> If I understand correctly, the CSS_ONLINE flag should be set in top_cpuset.css during the following
> process:
>
> css_create
> css = ss->css_alloc(parent_css); // cgroup root is static, unlike children
> online_css(css);
> ret = ss->css_online(css); // css root may differ from children
> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>
> I think css online must be successful, and it's CSS_ONLINE flag must be set. Do I missing anything?
I am talking about just the top_cpuset which is statically allocated. It
is not created by the css_create() call and so the CSS_ONLINE will not
be set.
Cheers,
Longman
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-13 1:00 ` Waiman Long
@ 2025-08-13 1:20 ` Chen Ridong
2025-08-13 1:33 ` Waiman Long
0 siblings, 1 reply; 14+ messages in thread
From: Chen Ridong @ 2025-08-13 1:20 UTC (permalink / raw)
To: Waiman Long, tj, hannes, mkoutny, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 2025/8/13 9:00, Waiman Long wrote:
> On 8/12/25 8:54 PM, Chen Ridong wrote:
>>
>> On 2025/8/12 22:44, Waiman Long wrote:
>>> On 8/8/25 5:25 AM, Chen Ridong wrote:
>>>> From: Chen Ridong <chenridong@huawei.com>
>>>>
>>>> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
>>>> cpuset subsystem. Currently, the flag setting sequence is as follows:
>>>>
>>>> 1. cpuset_css_online() sets CS_ONLINE
>>>> 2. css->flags gets CSS_ONLINE set
>>>> ...
>>>> 3. cgroup->kill_css sets CSS_DYING
>>>> 4. cpuset_css_offline() clears CS_ONLINE
>>>> 5. css->flags clears CSS_ONLINE
>>>>
>>>> The is_cpuset_online() check currently occurs between steps 1 and 3.
>>>> However, it would be equally safe to perform this check between steps 2
>>>> and 3, as CSS_ONLINE provides the same synchronization guarantee as
>>>> CS_ONLINE.
>>>>
>>>> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
>>>> synchronization benefits, we can safely remove it to simplify the code.
>>>>
>>>> Signed-off-by: Chen Ridong <chenridong@huawei.com>
>>>> ---
>>>> include/linux/cgroup.h | 5 +++++
>>>> kernel/cgroup/cpuset-internal.h | 3 +--
>>>> kernel/cgroup/cpuset.c | 4 +---
>>>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>>>> index b18fb5fcb38e..ae73dbb19165 100644
>>>> --- a/include/linux/cgroup.h
>>>> +++ b/include/linux/cgroup.h
>>>> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
>>>> return css->flags & CSS_DYING;
>>>> }
>>>> +static inline bool css_is_online(struct cgroup_subsys_state *css)
>>>> +{
>>>> + return css->flags & CSS_ONLINE;
>>>> +}
>>>> +
>>>> static inline bool css_is_self(struct cgroup_subsys_state *css)
>>>> {
>>>> if (css == &css->cgroup->self) {
>>>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>>>> index 383963e28ac6..75b3aef39231 100644
>>>> --- a/kernel/cgroup/cpuset-internal.h
>>>> +++ b/kernel/cgroup/cpuset-internal.h
>>>> @@ -38,7 +38,6 @@ enum prs_errcode {
>>>> /* bits in struct cpuset flags field */
>>>> typedef enum {
>>>> - CS_ONLINE,
>>>> CS_CPU_EXCLUSIVE,
>>>> CS_MEM_EXCLUSIVE,
>>>> CS_MEM_HARDWALL,
>>>> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
>>>> /* convenient tests for these bits */
>>>> static inline bool is_cpuset_online(struct cpuset *cs)
>>>> {
>>>> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
>>>> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
>>>> }
>>>> static inline int is_cpu_exclusive(const struct cpuset *cs)
>>>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>>>> index f74d04429a29..cf7cd2255265 100644
>>>> --- a/kernel/cgroup/cpuset.c
>>>> +++ b/kernel/cgroup/cpuset.c
>>>> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
>>>> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
>>>> */
>>>> static struct cpuset top_cpuset = {
>>>> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
>>>> + .flags = BIT(CS_CPU_EXCLUSIVE) |
>>>> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
>>>> .partition_root_state = PRS_ROOT,
>>>> .relax_domain_level = -1,
>>> top_cpuset.css is not initialized like the one in the children. If you modify is_cpuset_online() to
>>> test the css.flags, you will probably need to set the CSS_ONLINE flag in top_cpuset.css.flags. I do
>>> doubt that we will apply the is_cpuset_online() test on top_cpuset. To be consistent, we should
>>> support that.
>>>
>>> BTW, other statically allocated css'es in the cgroup root may have similar problem. If you make the
>>> css_is_online() helper available to all other controllers, you will have to document that
>>> limitation.
>>>
>>> Cheers,
>>> Longman
>> Hi, Longman, thank you for your response.
>>
>> If I understand correctly, the CSS_ONLINE flag should be set in top_cpuset.css during the following
>> process:
>>
>> css_create
>> css = ss->css_alloc(parent_css); // cgroup root is static, unlike children
>> online_css(css);
>> ret = ss->css_online(css); // css root may differ from children
>> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>>
>> I think css online must be successful, and it's CSS_ONLINE flag must be set. Do I missing anything?
>
> I am talking about just the top_cpuset which is statically allocated. It is not created by the
> css_create() call and so the CSS_ONLINE will not be set.
>
> Cheers,
> Longman
Hi Longman,
Apologies for the call stack earlier. Thank you for your patience in clarifying this matter.
The CSS root is brought online through the following initialization flow:
cgroup_init_subsys
css = ss->css_alloc(NULL); // css root is static, unlike children
online_css(css)
ret = ss->css_online(css); // css root may differ from children
css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
My key point is that:
- The root CSS should be online by design.
- Root css CSS_ONLINE flag should be properly set during initialization.
Best regards,
Ridong
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-13 1:20 ` Chen Ridong
@ 2025-08-13 1:33 ` Waiman Long
2025-08-13 6:28 ` Chen Ridong
0 siblings, 1 reply; 14+ messages in thread
From: Waiman Long @ 2025-08-13 1:33 UTC (permalink / raw)
To: Chen Ridong, Waiman Long, tj, hannes, mkoutny, mingo, peterz,
juri.lelli, vincent.guittot, dietmar.eggemann, rostedt, bsegall,
mgorman, vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 8/12/25 9:20 PM, Chen Ridong wrote:
>
> On 2025/8/13 9:00, Waiman Long wrote:
>> On 8/12/25 8:54 PM, Chen Ridong wrote:
>>> On 2025/8/12 22:44, Waiman Long wrote:
>>>> On 8/8/25 5:25 AM, Chen Ridong wrote:
>>>>> From: Chen Ridong <chenridong@huawei.com>
>>>>>
>>>>> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
>>>>> cpuset subsystem. Currently, the flag setting sequence is as follows:
>>>>>
>>>>> 1. cpuset_css_online() sets CS_ONLINE
>>>>> 2. css->flags gets CSS_ONLINE set
>>>>> ...
>>>>> 3. cgroup->kill_css sets CSS_DYING
>>>>> 4. cpuset_css_offline() clears CS_ONLINE
>>>>> 5. css->flags clears CSS_ONLINE
>>>>>
>>>>> The is_cpuset_online() check currently occurs between steps 1 and 3.
>>>>> However, it would be equally safe to perform this check between steps 2
>>>>> and 3, as CSS_ONLINE provides the same synchronization guarantee as
>>>>> CS_ONLINE.
>>>>>
>>>>> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
>>>>> synchronization benefits, we can safely remove it to simplify the code.
>>>>>
>>>>> Signed-off-by: Chen Ridong <chenridong@huawei.com>
>>>>> ---
>>>>> include/linux/cgroup.h | 5 +++++
>>>>> kernel/cgroup/cpuset-internal.h | 3 +--
>>>>> kernel/cgroup/cpuset.c | 4 +---
>>>>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>>>>> index b18fb5fcb38e..ae73dbb19165 100644
>>>>> --- a/include/linux/cgroup.h
>>>>> +++ b/include/linux/cgroup.h
>>>>> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
>>>>> return css->flags & CSS_DYING;
>>>>> }
>>>>> +static inline bool css_is_online(struct cgroup_subsys_state *css)
>>>>> +{
>>>>> + return css->flags & CSS_ONLINE;
>>>>> +}
>>>>> +
>>>>> static inline bool css_is_self(struct cgroup_subsys_state *css)
>>>>> {
>>>>> if (css == &css->cgroup->self) {
>>>>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>>>>> index 383963e28ac6..75b3aef39231 100644
>>>>> --- a/kernel/cgroup/cpuset-internal.h
>>>>> +++ b/kernel/cgroup/cpuset-internal.h
>>>>> @@ -38,7 +38,6 @@ enum prs_errcode {
>>>>> /* bits in struct cpuset flags field */
>>>>> typedef enum {
>>>>> - CS_ONLINE,
>>>>> CS_CPU_EXCLUSIVE,
>>>>> CS_MEM_EXCLUSIVE,
>>>>> CS_MEM_HARDWALL,
>>>>> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
>>>>> /* convenient tests for these bits */
>>>>> static inline bool is_cpuset_online(struct cpuset *cs)
>>>>> {
>>>>> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
>>>>> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
>>>>> }
>>>>> static inline int is_cpu_exclusive(const struct cpuset *cs)
>>>>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>>>>> index f74d04429a29..cf7cd2255265 100644
>>>>> --- a/kernel/cgroup/cpuset.c
>>>>> +++ b/kernel/cgroup/cpuset.c
>>>>> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
>>>>> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
>>>>> */
>>>>> static struct cpuset top_cpuset = {
>>>>> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
>>>>> + .flags = BIT(CS_CPU_EXCLUSIVE) |
>>>>> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
>>>>> .partition_root_state = PRS_ROOT,
>>>>> .relax_domain_level = -1,
>>>> top_cpuset.css is not initialized like the one in the children. If you modify is_cpuset_online() to
>>>> test the css.flags, you will probably need to set the CSS_ONLINE flag in top_cpuset.css.flags. I do
>>>> doubt that we will apply the is_cpuset_online() test on top_cpuset. To be consistent, we should
>>>> support that.
>>>>
>>>> BTW, other statically allocated css'es in the cgroup root may have similar problem. If you make the
>>>> css_is_online() helper available to all other controllers, you will have to document that
>>>> limitation.
>>>>
>>>> Cheers,
>>>> Longman
>>> Hi, Longman, thank you for your response.
>>>
>>> If I understand correctly, the CSS_ONLINE flag should be set in top_cpuset.css during the following
>>> process:
>>>
>>> css_create
>>> css = ss->css_alloc(parent_css); // cgroup root is static, unlike children
>>> online_css(css);
>>> ret = ss->css_online(css); // css root may differ from children
>>> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>>>
>>> I think css online must be successful, and it's CSS_ONLINE flag must be set. Do I missing anything?
>> I am talking about just the top_cpuset which is statically allocated. It is not created by the
>> css_create() call and so the CSS_ONLINE will not be set.
>>
>> Cheers,
>> Longman
> Hi Longman,
>
> Apologies for the call stack earlier. Thank you for your patience in clarifying this matter.
>
> The CSS root is brought online through the following initialization flow:
>
> cgroup_init_subsys
> css = ss->css_alloc(NULL); // css root is static, unlike children
> online_css(css)
> ret = ss->css_online(css); // css root may differ from children
> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>
> My key point is that:
> - The root CSS should be online by design.
> - Root css CSS_ONLINE flag should be properly set during initialization.
Yes, you are right. I missed css_online() call for the root css for each
controller. Thanks for the clarification.
With that, I am OK with this patch. Though the other ones are not good.
Acked-by: Waiman Long <longman@redhat.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag
2025-08-13 1:33 ` Waiman Long
@ 2025-08-13 6:28 ` Chen Ridong
0 siblings, 0 replies; 14+ messages in thread
From: Chen Ridong @ 2025-08-13 6:28 UTC (permalink / raw)
To: Waiman Long, tj, hannes, mkoutny, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
On 2025/8/13 9:33, Waiman Long wrote:
>
> On 8/12/25 9:20 PM, Chen Ridong wrote:
>>
>> On 2025/8/13 9:00, Waiman Long wrote:
>>> On 8/12/25 8:54 PM, Chen Ridong wrote:
>>>> On 2025/8/12 22:44, Waiman Long wrote:
>>>>> On 8/8/25 5:25 AM, Chen Ridong wrote:
>>>>>> From: Chen Ridong <chenridong@huawei.com>
>>>>>>
>>>>>> The CS_ONLINE flag was introduced prior to the CSS_ONLINE flag in the
>>>>>> cpuset subsystem. Currently, the flag setting sequence is as follows:
>>>>>>
>>>>>> 1. cpuset_css_online() sets CS_ONLINE
>>>>>> 2. css->flags gets CSS_ONLINE set
>>>>>> ...
>>>>>> 3. cgroup->kill_css sets CSS_DYING
>>>>>> 4. cpuset_css_offline() clears CS_ONLINE
>>>>>> 5. css->flags clears CSS_ONLINE
>>>>>>
>>>>>> The is_cpuset_online() check currently occurs between steps 1 and 3.
>>>>>> However, it would be equally safe to perform this check between steps 2
>>>>>> and 3, as CSS_ONLINE provides the same synchronization guarantee as
>>>>>> CS_ONLINE.
>>>>>>
>>>>>> Since CS_ONLINE is redundant with CSS_ONLINE and provides no additional
>>>>>> synchronization benefits, we can safely remove it to simplify the code.
>>>>>>
>>>>>> Signed-off-by: Chen Ridong <chenridong@huawei.com>
>>>>>> ---
>>>>>> include/linux/cgroup.h | 5 +++++
>>>>>> kernel/cgroup/cpuset-internal.h | 3 +--
>>>>>> kernel/cgroup/cpuset.c | 4 +---
>>>>>> 3 files changed, 7 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>>>>>> index b18fb5fcb38e..ae73dbb19165 100644
>>>>>> --- a/include/linux/cgroup.h
>>>>>> +++ b/include/linux/cgroup.h
>>>>>> @@ -354,6 +354,11 @@ static inline bool css_is_dying(struct cgroup_subsys_state *css)
>>>>>> return css->flags & CSS_DYING;
>>>>>> }
>>>>>> +static inline bool css_is_online(struct cgroup_subsys_state *css)
>>>>>> +{
>>>>>> + return css->flags & CSS_ONLINE;
>>>>>> +}
>>>>>> +
>>>>>> static inline bool css_is_self(struct cgroup_subsys_state *css)
>>>>>> {
>>>>>> if (css == &css->cgroup->self) {
>>>>>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>>>>>> index 383963e28ac6..75b3aef39231 100644
>>>>>> --- a/kernel/cgroup/cpuset-internal.h
>>>>>> +++ b/kernel/cgroup/cpuset-internal.h
>>>>>> @@ -38,7 +38,6 @@ enum prs_errcode {
>>>>>> /* bits in struct cpuset flags field */
>>>>>> typedef enum {
>>>>>> - CS_ONLINE,
>>>>>> CS_CPU_EXCLUSIVE,
>>>>>> CS_MEM_EXCLUSIVE,
>>>>>> CS_MEM_HARDWALL,
>>>>>> @@ -202,7 +201,7 @@ static inline struct cpuset *parent_cs(struct cpuset *cs)
>>>>>> /* convenient tests for these bits */
>>>>>> static inline bool is_cpuset_online(struct cpuset *cs)
>>>>>> {
>>>>>> - return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
>>>>>> + return css_is_online(&cs->css) && !css_is_dying(&cs->css);
>>>>>> }
>>>>>> static inline int is_cpu_exclusive(const struct cpuset *cs)
>>>>>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>>>>>> index f74d04429a29..cf7cd2255265 100644
>>>>>> --- a/kernel/cgroup/cpuset.c
>>>>>> +++ b/kernel/cgroup/cpuset.c
>>>>>> @@ -207,7 +207,7 @@ static inline void notify_partition_change(struct cpuset *cs, int old_prs)
>>>>>> * parallel, we may leave an offline CPU in cpu_allowed or some other masks.
>>>>>> */
>>>>>> static struct cpuset top_cpuset = {
>>>>>> - .flags = BIT(CS_ONLINE) | BIT(CS_CPU_EXCLUSIVE) |
>>>>>> + .flags = BIT(CS_CPU_EXCLUSIVE) |
>>>>>> BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
>>>>>> .partition_root_state = PRS_ROOT,
>>>>>> .relax_domain_level = -1,
>>>>> top_cpuset.css is not initialized like the one in the children. If you modify
>>>>> is_cpuset_online() to
>>>>> test the css.flags, you will probably need to set the CSS_ONLINE flag in top_cpuset.css.flags.
>>>>> I do
>>>>> doubt that we will apply the is_cpuset_online() test on top_cpuset. To be consistent, we should
>>>>> support that.
>>>>>
>>>>> BTW, other statically allocated css'es in the cgroup root may have similar problem. If you make
>>>>> the
>>>>> css_is_online() helper available to all other controllers, you will have to document that
>>>>> limitation.
>>>>>
>>>>> Cheers,
>>>>> Longman
>>>> Hi, Longman, thank you for your response.
>>>>
>>>> If I understand correctly, the CSS_ONLINE flag should be set in top_cpuset.css during the following
>>>> process:
>>>>
>>>> css_create
>>>> css = ss->css_alloc(parent_css); // cgroup root is static, unlike children
>>>> online_css(css);
>>>> ret = ss->css_online(css); // css root may differ from children
>>>> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>>>>
>>>> I think css online must be successful, and it's CSS_ONLINE flag must be set. Do I missing anything?
>>> I am talking about just the top_cpuset which is statically allocated. It is not created by the
>>> css_create() call and so the CSS_ONLINE will not be set.
>>>
>>> Cheers,
>>> Longman
>> Hi Longman,
>>
>> Apologies for the call stack earlier. Thank you for your patience in clarifying this matter.
>>
>> The CSS root is brought online through the following initialization flow:
>>
>> cgroup_init_subsys
>> css = ss->css_alloc(NULL); // css root is static, unlike children
>> online_css(css)
>> ret = ss->css_online(css); // css root may differ from children
>> css->flags |= CSS_ONLINE; // css.flags is set with CSS_ONLINE, including the root css
>>
>> My key point is that:
>> - The root CSS should be online by design.
>> - Root css CSS_ONLINE flag should be properly set during initialization.
>
> Yes, you are right. I missed css_online() call for the root css for each controller. Thanks for the
> clarification.
>
> With that, I am OK with this patch. Though the other ones are not good.
>
> Acked-by: Waiman Long <longman@redhat.com>
Thank you.
I will send v2 to fix the others.
Best regard,
Ridong
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH -next 2/4] cpuset: add helpers for cpuset related locks
2025-08-08 9:25 [PATCH -next 0/4] some optimization for cpuset Chen Ridong
2025-08-08 9:25 ` [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag Chen Ridong
@ 2025-08-08 9:25 ` Chen Ridong
2025-08-09 15:56 ` Christophe JAILLET
2025-08-08 9:25 ` [PATCH -next 3/4] cpuset: use guard_cpus_read_and_cpuset to make code concise Chen Ridong
2025-08-08 9:25 ` [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset() Chen Ridong
3 siblings, 1 reply; 14+ messages in thread
From: Chen Ridong @ 2025-08-08 9:25 UTC (permalink / raw)
To: tj, hannes, mkoutny, longman, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
From: Chen Ridong <chenridong@huawei.com>
Add guard_cpus_read_and_cpuset and guard_cpuset helpers for cpuset, which
will be user for subsequent patched to make code concise;
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
include/linux/cpuset.h | 1 +
kernel/cgroup/cpuset-internal.h | 2 ++
kernel/cgroup/cpuset.c | 11 +++++++++++
3 files changed, 14 insertions(+)
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 2ddb256187b5..6153de28acf0 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -74,6 +74,7 @@ extern void inc_dl_tasks_cs(struct task_struct *task);
extern void dec_dl_tasks_cs(struct task_struct *task);
extern void cpuset_lock(void);
extern void cpuset_unlock(void);
+extern void guard_cpuset(void);
extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
extern bool cpuset_cpu_is_isolated(int cpu);
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
index 75b3aef39231..084e19fe33d5 100644
--- a/kernel/cgroup/cpuset-internal.h
+++ b/kernel/cgroup/cpuset-internal.h
@@ -277,6 +277,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
char *buf, size_t nbytes, loff_t off);
int cpuset_common_seq_show(struct seq_file *sf, void *v);
+void guard_cpus_read_and_cpuset(void);
+
/*
* cpuset-v1.c
*/
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index cf7cd2255265..f6cdb5cdffe8 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -260,6 +260,17 @@ void cpuset_unlock(void)
mutex_unlock(&cpuset_mutex);
}
+void guard_cpuset(void)
+{
+ guard(mutex)(&cpuset_mutex);
+}
+
+void guard_cpus_read_and_cpuset(void)
+{
+ guard(cpus_read_lock)();
+ guard(mutex)(&cpuset_mutex);
+}
+
static DEFINE_SPINLOCK(callback_lock);
void cpuset_callback_lock_irq(void)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH -next 2/4] cpuset: add helpers for cpuset related locks
2025-08-08 9:25 ` [PATCH -next 2/4] cpuset: add helpers for cpuset related locks Chen Ridong
@ 2025-08-09 15:56 ` Christophe JAILLET
2025-08-11 2:17 ` Chen Ridong
0 siblings, 1 reply; 14+ messages in thread
From: Christophe JAILLET @ 2025-08-09 15:56 UTC (permalink / raw)
To: chenridong
Cc: bsegall, cgroups, chenridong, dietmar.eggemann, hannes,
juri.lelli, linux-kernel, longman, lujialin4, mgorman, mingo,
mkoutny, peterz, rostedt, tj, vincent.guittot, vschneid
Le 08/08/2025 à 11:25, Chen Ridong a écrit :
> From: Chen Ridong <chenridong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>
> Add guard_cpus_read_and_cpuset and guard_cpuset helpers for cpuset, which
> will be user for subsequent patched to make code concise;
>
> Signed-off-by: Chen Ridong <chenridong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
> include/linux/cpuset.h | 1 +
> kernel/cgroup/cpuset-internal.h | 2 ++
> kernel/cgroup/cpuset.c | 11 +++++++++++
> 3 files changed, 14 insertions(+)
>
> diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
> index 2ddb256187b5..6153de28acf0 100644
> --- a/include/linux/cpuset.h
> +++ b/include/linux/cpuset.h
> @@ -74,6 +74,7 @@ extern void inc_dl_tasks_cs(struct task_struct *task);
> extern void dec_dl_tasks_cs(struct task_struct *task);
> extern void cpuset_lock(void);
> extern void cpuset_unlock(void);
> +extern void guard_cpuset(void);
> extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
> extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
> extern bool cpuset_cpu_is_isolated(int cpu);
> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
> index 75b3aef39231..084e19fe33d5 100644
> --- a/kernel/cgroup/cpuset-internal.h
> +++ b/kernel/cgroup/cpuset-internal.h
> @@ -277,6 +277,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
> char *buf, size_t nbytes, loff_t off);
> int cpuset_common_seq_show(struct seq_file *sf, void *v);
>
> +void guard_cpus_read_and_cpuset(void);
> +
> /*
> * cpuset-v1.c
> */
> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
> index cf7cd2255265..f6cdb5cdffe8 100644
> --- a/kernel/cgroup/cpuset.c
> +++ b/kernel/cgroup/cpuset.c
> @@ -260,6 +260,17 @@ void cpuset_unlock(void)
> mutex_unlock(&cpuset_mutex);
> }
>
> +void guard_cpuset(void)
> +{
> + guard(mutex)(&cpuset_mutex);
> +}
> +
> +void guard_cpus_read_and_cpuset(void)
> +{
> + guard(cpus_read_lock)();
> + guard(mutex)(&cpuset_mutex);
> +}
> +
Not sure that it works like that.
I think that these 2 functions are just no-op because whatever is
"garded", it will be release when the function exits.
So, if correct, all this serie does is removing some existing
synchronisation mechanism.
Do I miss something obvious?
CJ
> static DEFINE_SPINLOCK(callback_lock);
>
> void cpuset_callback_lock_irq(void)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH -next 2/4] cpuset: add helpers for cpuset related locks
2025-08-09 15:56 ` Christophe JAILLET
@ 2025-08-11 2:17 ` Chen Ridong
0 siblings, 0 replies; 14+ messages in thread
From: Chen Ridong @ 2025-08-11 2:17 UTC (permalink / raw)
To: Christophe JAILLET
Cc: bsegall, cgroups, chenridong, dietmar.eggemann, hannes,
juri.lelli, linux-kernel, longman, lujialin4, mgorman, mingo,
mkoutny, peterz, rostedt, tj, vincent.guittot, vschneid
On 2025/8/9 23:56, Christophe JAILLET wrote:
> Le 08/08/2025 à 11:25, Chen Ridong a écrit :
>> From: Chen Ridong <chenridong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>>
>> Add guard_cpus_read_and_cpuset and guard_cpuset helpers for cpuset, which
>> will be user for subsequent patched to make code concise;
>>
>> Signed-off-by: Chen Ridong <chenridong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
>> include/linux/cpuset.h | 1 +
>> kernel/cgroup/cpuset-internal.h | 2 ++
>> kernel/cgroup/cpuset.c | 11 +++++++++++
>> 3 files changed, 14 insertions(+)
>>
>> diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
>> index 2ddb256187b5..6153de28acf0 100644
>> --- a/include/linux/cpuset.h
>> +++ b/include/linux/cpuset.h
>> @@ -74,6 +74,7 @@ extern void inc_dl_tasks_cs(struct task_struct *task);
>> extern void dec_dl_tasks_cs(struct task_struct *task);
>> extern void cpuset_lock(void);
>> extern void cpuset_unlock(void);
>> +extern void guard_cpuset(void);
>> extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
>> extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
>> extern bool cpuset_cpu_is_isolated(int cpu);
>> diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h
>> index 75b3aef39231..084e19fe33d5 100644
>> --- a/kernel/cgroup/cpuset-internal.h
>> +++ b/kernel/cgroup/cpuset-internal.h
>> @@ -277,6 +277,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
>> char *buf, size_t nbytes, loff_t off);
>> int cpuset_common_seq_show(struct seq_file *sf, void *v);
>> +void guard_cpus_read_and_cpuset(void);
>> +
>> /*
>> * cpuset-v1.c
>> */
>> diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
>> index cf7cd2255265..f6cdb5cdffe8 100644
>> --- a/kernel/cgroup/cpuset.c
>> +++ b/kernel/cgroup/cpuset.c
>> @@ -260,6 +260,17 @@ void cpuset_unlock(void)
>> mutex_unlock(&cpuset_mutex);
>> }
>> +void guard_cpuset(void)
>> +{
>> + guard(mutex)(&cpuset_mutex);
>> +}
>> +
>> +void guard_cpus_read_and_cpuset(void)
>> +{
>> + guard(cpus_read_lock)();
>> + guard(mutex)(&cpuset_mutex);
>> +}
>> +
>
> Not sure that it works like that.
>
> I think that these 2 functions are just no-op because whatever is "garded", it will be release when
> the function exits.
>
> So, if correct, all this serie does is removing some existing synchronisation mechanism.
>
> Do I miss something obvious?
>
> CJ
>
Thank you for catching this issue. You're absolutely right - I made a critical mistake in the guard
function implementation.
After further investigation, I realized that when I ran the self-tests with CONFIG_LOCKDEP disabled,
I missed the lock protection warnings that would have revealed this problem earlier. Had Lockdep
been enabled, it would have immediately flagged the incorrect locking behavior.
Please ignore this patch series, Thanks.
Best regards,
Ridong
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH -next 3/4] cpuset: use guard_cpus_read_and_cpuset to make code concise
2025-08-08 9:25 [PATCH -next 0/4] some optimization for cpuset Chen Ridong
2025-08-08 9:25 ` [PATCH -next 1/4] cpuset: remove redundant CS_ONLINE flag Chen Ridong
2025-08-08 9:25 ` [PATCH -next 2/4] cpuset: add helpers for cpuset related locks Chen Ridong
@ 2025-08-08 9:25 ` Chen Ridong
2025-08-08 9:25 ` [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset() Chen Ridong
3 siblings, 0 replies; 14+ messages in thread
From: Chen Ridong @ 2025-08-08 9:25 UTC (permalink / raw)
To: tj, hannes, mkoutny, longman, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
From: Chen Ridong <chenridong@huawei.com>
Several functions currently implement manual locking sequences for both
cpus_read_lock() and cpuset_mutex. Replace these repetitive patterns
with the new guard_cpus_read_and_cpuset() helper.
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
kernel/cgroup/cpuset-v1.c | 22 +++++++---------------
kernel/cgroup/cpuset.c | 39 ++++++++++-----------------------------
2 files changed, 17 insertions(+), 44 deletions(-)
diff --git a/kernel/cgroup/cpuset-v1.c b/kernel/cgroup/cpuset-v1.c
index b69a7db67090..70685b90759c 100644
--- a/kernel/cgroup/cpuset-v1.c
+++ b/kernel/cgroup/cpuset-v1.c
@@ -169,10 +169,10 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private;
int retval = -ENODEV;
- cpus_read_lock();
- cpuset_lock();
+ guard_cpus_read_and_cpuset();
+
if (!is_cpuset_online(cs))
- goto out_unlock;
+ return retval;
switch (type) {
case FILE_SCHED_RELAX_DOMAIN_LEVEL:
@@ -183,9 +183,6 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
retval = -EINVAL;
break;
}
-out_unlock:
- cpuset_unlock();
- cpus_read_unlock();
return retval;
}
@@ -454,12 +451,9 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private;
int retval = 0;
- cpus_read_lock();
- cpuset_lock();
- if (!is_cpuset_online(cs)) {
- retval = -ENODEV;
- goto out_unlock;
- }
+ guard_cpus_read_and_cpuset();
+ if (!is_cpuset_online(cs))
+ return -ENODEV;
switch (type) {
case FILE_CPU_EXCLUSIVE:
@@ -497,9 +491,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
retval = -EINVAL;
break;
}
-out_unlock:
- cpuset_unlock();
- cpus_read_unlock();
+
return retval;
}
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index f6cdb5cdffe8..110d2b93ff96 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -3235,15 +3235,14 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
int retval = -ENODEV;
buf = strstrip(buf);
- cpus_read_lock();
- mutex_lock(&cpuset_mutex);
+ guard_cpus_read_and_cpuset();
if (!is_cpuset_online(cs))
- goto out_unlock;
+ goto out;
trialcs = alloc_trial_cpuset(cs);
if (!trialcs) {
retval = -ENOMEM;
- goto out_unlock;
+ goto out;
}
switch (of_cft(of)->private) {
@@ -3264,9 +3263,7 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
free_cpuset(trialcs);
if (force_sd_rebuild)
rebuild_sched_domains_locked();
-out_unlock:
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
+out:
flush_workqueue(cpuset_migrate_mm_wq);
return retval ?: nbytes;
}
@@ -3370,12 +3367,9 @@ static ssize_t cpuset_partition_write(struct kernfs_open_file *of, char *buf,
return -EINVAL;
css_get(&cs->css);
- cpus_read_lock();
- mutex_lock(&cpuset_mutex);
+ guard_cpus_read_and_cpuset();
if (is_cpuset_online(cs))
retval = update_prstate(cs, val);
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
css_put(&cs->css);
return retval ?: nbytes;
}
@@ -3506,8 +3500,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
if (!parent)
return 0;
- cpus_read_lock();
- mutex_lock(&cpuset_mutex);
+ guard_cpus_read_and_cpuset();
if (is_spread_page(parent))
set_bit(CS_SPREAD_PAGE, &cs->flags);
@@ -3529,7 +3522,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
spin_unlock_irq(&callback_lock);
if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags))
- goto out_unlock;
+ return 0;
/*
* Clone @parent's configuration if CGRP_CPUSET_CLONE_CHILDREN is
@@ -3548,7 +3541,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
cpuset_for_each_child(tmp_cs, pos_css, parent) {
if (is_mem_exclusive(tmp_cs) || is_cpu_exclusive(tmp_cs)) {
rcu_read_unlock();
- goto out_unlock;
+ return 0;
}
}
rcu_read_unlock();
@@ -3559,9 +3552,6 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
cpumask_copy(cs->cpus_allowed, parent->cpus_allowed);
cpumask_copy(cs->effective_cpus, parent->cpus_allowed);
spin_unlock_irq(&callback_lock);
-out_unlock:
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
return 0;
}
@@ -3576,16 +3566,12 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
{
struct cpuset *cs = css_cs(css);
- cpus_read_lock();
- mutex_lock(&cpuset_mutex);
+ guard_cpus_read_and_cpuset();
if (!cpuset_v2() && is_sched_load_balance(cs))
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
cpuset_dec();
-
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
}
/*
@@ -3597,16 +3583,11 @@ static void cpuset_css_killed(struct cgroup_subsys_state *css)
{
struct cpuset *cs = css_cs(css);
- cpus_read_lock();
- mutex_lock(&cpuset_mutex);
+ guard_cpus_read_and_cpuset();
/* Reset valid partition back to member */
if (is_partition_valid(cs))
update_prstate(cs, PRS_MEMBER);
-
- mutex_unlock(&cpuset_mutex);
- cpus_read_unlock();
-
}
static void cpuset_css_free(struct cgroup_subsys_state *css)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset()
2025-08-08 9:25 [PATCH -next 0/4] some optimization for cpuset Chen Ridong
` (2 preceding siblings ...)
2025-08-08 9:25 ` [PATCH -next 3/4] cpuset: use guard_cpus_read_and_cpuset to make code concise Chen Ridong
@ 2025-08-08 9:25 ` Chen Ridong
2025-08-08 22:02 ` kernel test robot
3 siblings, 1 reply; 14+ messages in thread
From: Chen Ridong @ 2025-08-08 9:25 UTC (permalink / raw)
To: tj, hannes, mkoutny, longman, mingo, peterz, juri.lelli,
vincent.guittot, dietmar.eggemann, rostedt, bsegall, mgorman,
vschneid
Cc: cgroups, linux-kernel, lujialin4, chenridong
From: Chen Ridong <chenridong@huawei.com>
The guard_cpuset() is introduced, we can replace all cpuset_lock()
usage with it and remove the cpuset_lock().
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
include/linux/cpuset.h | 2 --
kernel/cgroup/cpuset.c | 10 ----------
kernel/sched/syscalls.c | 15 +++++----------
3 files changed, 5 insertions(+), 22 deletions(-)
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 6153de28acf0..1baf12f4be19 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -72,8 +72,6 @@ extern void cpuset_force_rebuild(void);
extern void cpuset_update_active_cpus(void);
extern void inc_dl_tasks_cs(struct task_struct *task);
extern void dec_dl_tasks_cs(struct task_struct *task);
-extern void cpuset_lock(void);
-extern void cpuset_unlock(void);
extern void guard_cpuset(void);
extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
extern bool cpuset_cpus_allowed_fallback(struct task_struct *p);
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 110d2b93ff96..04ed73d0887e 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -250,16 +250,6 @@ static struct cpuset top_cpuset = {
static DEFINE_MUTEX(cpuset_mutex);
-void cpuset_lock(void)
-{
- mutex_lock(&cpuset_mutex);
-}
-
-void cpuset_unlock(void)
-{
- mutex_unlock(&cpuset_mutex);
-}
-
void guard_cpuset(void)
{
guard(mutex)(&cpuset_mutex);
diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
index 77ae87f36e84..954f6e9af41b 100644
--- a/kernel/sched/syscalls.c
+++ b/kernel/sched/syscalls.c
@@ -577,8 +577,10 @@ int __sched_setscheduler(struct task_struct *p,
* information.
*/
if (dl_policy(policy) || dl_policy(p->policy)) {
- cpuset_locked = true;
- cpuset_lock();
+ if (!cpuset_locked) {
+ guard_cpuset();
+ cpuset_locked = true;
+ }
}
/*
@@ -660,8 +662,6 @@ int __sched_setscheduler(struct task_struct *p,
if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
policy = oldpolicy = -1;
task_rq_unlock(rq, p, &rf);
- if (cpuset_locked)
- cpuset_unlock();
goto recheck;
}
@@ -733,11 +733,8 @@ int __sched_setscheduler(struct task_struct *p,
head = splice_balance_callbacks(rq);
task_rq_unlock(rq, p, &rf);
- if (pi) {
- if (cpuset_locked)
- cpuset_unlock();
+ if (pi)
rt_mutex_adjust_pi(p);
- }
/* Run balance callbacks after we've adjusted the PI chain: */
balance_callbacks(rq, head);
@@ -747,8 +744,6 @@ int __sched_setscheduler(struct task_struct *p,
unlock:
task_rq_unlock(rq, p, &rf);
- if (cpuset_locked)
- cpuset_unlock();
return retval;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset()
2025-08-08 9:25 ` [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset() Chen Ridong
@ 2025-08-08 22:02 ` kernel test robot
0 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2025-08-08 22:02 UTC (permalink / raw)
To: Chen Ridong, tj, hannes, mkoutny, longman, mingo, peterz,
juri.lelli, vincent.guittot, dietmar.eggemann, rostedt, bsegall,
mgorman, vschneid
Cc: oe-kbuild-all, cgroups, linux-kernel, lujialin4, chenridong
Hi Chen,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20250808]
url: https://github.com/intel-lab-lkp/linux/commits/Chen-Ridong/cpuset-remove-redundant-CS_ONLINE-flag/20250808-174245
base: next-20250808
patch link: https://lore.kernel.org/r/20250808092515.764820-5-chenridong%40huaweicloud.com
patch subject: [PATCH -next 4/4] cpuset: replace cpuset_lock() with guard_cpuset()
config: x86_64-buildonly-randconfig-001-20250809 (https://download.01.org/0day-ci/archive/20250809/202508090557.XjdGVjX4-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250809/202508090557.XjdGVjX4-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508090557.XjdGVjX4-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from kernel/sched/build_policy.c:65:
kernel/sched/syscalls.c: In function '__sched_setscheduler':
>> kernel/sched/syscalls.c:581:25: error: implicit declaration of function 'guard_cpuset' [-Werror=implicit-function-declaration]
581 | guard_cpuset();
| ^~~~~~~~~~~~
In file included from kernel/sched/build_policy.c:52:
kernel/sched/rt.c: At top level:
kernel/sched/rt.c:12:18: warning: 'max_rt_runtime' defined but not used [-Wunused-const-variable=]
12 | static const u64 max_rt_runtime = MAX_BW;
| ^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/guard_cpuset +581 kernel/sched/syscalls.c
512
513 int __sched_setscheduler(struct task_struct *p,
514 const struct sched_attr *attr,
515 bool user, bool pi)
516 {
517 int oldpolicy = -1, policy = attr->sched_policy;
518 int retval, oldprio, newprio, queued, running;
519 const struct sched_class *prev_class, *next_class;
520 struct balance_callback *head;
521 struct rq_flags rf;
522 int reset_on_fork;
523 int queue_flags = DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK;
524 struct rq *rq;
525 bool cpuset_locked = false;
526
527 /* The pi code expects interrupts enabled */
528 BUG_ON(pi && in_interrupt());
529 recheck:
530 /* Double check policy once rq lock held: */
531 if (policy < 0) {
532 reset_on_fork = p->sched_reset_on_fork;
533 policy = oldpolicy = p->policy;
534 } else {
535 reset_on_fork = !!(attr->sched_flags & SCHED_FLAG_RESET_ON_FORK);
536
537 if (!valid_policy(policy))
538 return -EINVAL;
539 }
540
541 if (attr->sched_flags & ~(SCHED_FLAG_ALL | SCHED_FLAG_SUGOV))
542 return -EINVAL;
543
544 /*
545 * Valid priorities for SCHED_FIFO and SCHED_RR are
546 * 1..MAX_RT_PRIO-1, valid priority for SCHED_NORMAL,
547 * SCHED_BATCH and SCHED_IDLE is 0.
548 */
549 if (attr->sched_priority > MAX_RT_PRIO-1)
550 return -EINVAL;
551 if ((dl_policy(policy) && !__checkparam_dl(attr)) ||
552 (rt_policy(policy) != (attr->sched_priority != 0)))
553 return -EINVAL;
554
555 if (user) {
556 retval = user_check_sched_setscheduler(p, attr, policy, reset_on_fork);
557 if (retval)
558 return retval;
559
560 if (attr->sched_flags & SCHED_FLAG_SUGOV)
561 return -EINVAL;
562
563 retval = security_task_setscheduler(p);
564 if (retval)
565 return retval;
566 }
567
568 /* Update task specific "requested" clamps */
569 if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) {
570 retval = uclamp_validate(p, attr);
571 if (retval)
572 return retval;
573 }
574
575 /*
576 * SCHED_DEADLINE bandwidth accounting relies on stable cpusets
577 * information.
578 */
579 if (dl_policy(policy) || dl_policy(p->policy)) {
580 if (!cpuset_locked) {
> 581 guard_cpuset();
582 cpuset_locked = true;
583 }
584 }
585
586 /*
587 * Make sure no PI-waiters arrive (or leave) while we are
588 * changing the priority of the task:
589 *
590 * To be able to change p->policy safely, the appropriate
591 * runqueue lock must be held.
592 */
593 rq = task_rq_lock(p, &rf);
594 update_rq_clock(rq);
595
596 /*
597 * Changing the policy of the stop threads its a very bad idea:
598 */
599 if (p == rq->stop) {
600 retval = -EINVAL;
601 goto unlock;
602 }
603
604 retval = scx_check_setscheduler(p, policy);
605 if (retval)
606 goto unlock;
607
608 /*
609 * If not changing anything there's no need to proceed further,
610 * but store a possible modification of reset_on_fork.
611 */
612 if (unlikely(policy == p->policy)) {
613 if (fair_policy(policy) &&
614 (attr->sched_nice != task_nice(p) ||
615 (attr->sched_runtime != p->se.slice)))
616 goto change;
617 if (rt_policy(policy) && attr->sched_priority != p->rt_priority)
618 goto change;
619 if (dl_policy(policy) && dl_param_changed(p, attr))
620 goto change;
621 if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP)
622 goto change;
623
624 p->sched_reset_on_fork = reset_on_fork;
625 retval = 0;
626 goto unlock;
627 }
628 change:
629
630 if (user) {
631 #ifdef CONFIG_RT_GROUP_SCHED
632 /*
633 * Do not allow real-time tasks into groups that have no runtime
634 * assigned.
635 */
636 if (rt_group_sched_enabled() &&
637 rt_bandwidth_enabled() && rt_policy(policy) &&
638 task_group(p)->rt_bandwidth.rt_runtime == 0 &&
639 !task_group_is_autogroup(task_group(p))) {
640 retval = -EPERM;
641 goto unlock;
642 }
643 #endif /* CONFIG_RT_GROUP_SCHED */
644 if (dl_bandwidth_enabled() && dl_policy(policy) &&
645 !(attr->sched_flags & SCHED_FLAG_SUGOV)) {
646 cpumask_t *span = rq->rd->span;
647
648 /*
649 * Don't allow tasks with an affinity mask smaller than
650 * the entire root_domain to become SCHED_DEADLINE. We
651 * will also fail if there's no bandwidth available.
652 */
653 if (!cpumask_subset(span, p->cpus_ptr) ||
654 rq->rd->dl_bw.bw == 0) {
655 retval = -EPERM;
656 goto unlock;
657 }
658 }
659 }
660
661 /* Re-check policy now with rq lock held: */
662 if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
663 policy = oldpolicy = -1;
664 task_rq_unlock(rq, p, &rf);
665 goto recheck;
666 }
667
668 /*
669 * If setscheduling to SCHED_DEADLINE (or changing the parameters
670 * of a SCHED_DEADLINE task) we need to check if enough bandwidth
671 * is available.
672 */
673 if ((dl_policy(policy) || dl_task(p)) && sched_dl_overflow(p, policy, attr)) {
674 retval = -EBUSY;
675 goto unlock;
676 }
677
678 p->sched_reset_on_fork = reset_on_fork;
679 oldprio = p->prio;
680
681 newprio = __normal_prio(policy, attr->sched_priority, attr->sched_nice);
682 if (pi) {
683 /*
684 * Take priority boosted tasks into account. If the new
685 * effective priority is unchanged, we just store the new
686 * normal parameters and do not touch the scheduler class and
687 * the runqueue. This will be done when the task deboost
688 * itself.
689 */
690 newprio = rt_effective_prio(p, newprio);
691 if (newprio == oldprio)
692 queue_flags &= ~DEQUEUE_MOVE;
693 }
694
695 prev_class = p->sched_class;
696 next_class = __setscheduler_class(policy, newprio);
697
698 if (prev_class != next_class && p->se.sched_delayed)
699 dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
700
701 queued = task_on_rq_queued(p);
702 running = task_current_donor(rq, p);
703 if (queued)
704 dequeue_task(rq, p, queue_flags);
705 if (running)
706 put_prev_task(rq, p);
707
708 if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
709 __setscheduler_params(p, attr);
710 p->sched_class = next_class;
711 p->prio = newprio;
712 }
713 __setscheduler_uclamp(p, attr);
714 check_class_changing(rq, p, prev_class);
715
716 if (queued) {
717 /*
718 * We enqueue to tail when the priority of a task is
719 * increased (user space view).
720 */
721 if (oldprio < p->prio)
722 queue_flags |= ENQUEUE_HEAD;
723
724 enqueue_task(rq, p, queue_flags);
725 }
726 if (running)
727 set_next_task(rq, p);
728
729 check_class_changed(rq, p, prev_class, oldprio);
730
731 /* Avoid rq from going away on us: */
732 preempt_disable();
733 head = splice_balance_callbacks(rq);
734 task_rq_unlock(rq, p, &rf);
735
736 if (pi)
737 rt_mutex_adjust_pi(p);
738
739 /* Run balance callbacks after we've adjusted the PI chain: */
740 balance_callbacks(rq, head);
741 preempt_enable();
742
743 return 0;
744
745 unlock:
746 task_rq_unlock(rq, p, &rf);
747 return retval;
748 }
749
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 14+ messages in thread