* [PATHC v3 -next 0/3] Some optimizations about freezer
@ 2024-09-15 7:13 Chen Ridong
2024-09-15 7:13 ` [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze Chen Ridong
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Chen Ridong @ 2024-09-15 7:13 UTC (permalink / raw)
To: tj, lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro; +Cc: cgroups
I optimized the freezer to reduce redundant loops, and I add helper
to make code concise.
The following subtree was tested to prove whether my optimizations are
effective.
0
/ | \ \
A B C 1
/ | \ \
A B C 2
.....
n
/ | \
A B C
I tested by following steps:
1. freeze 0
2. unfreeze 0
3. freeze 0
4. freeze 1
And I measured the elapsed time(ns).
n=10
freeze 0 unfreeze 0 freeze 0 freeze 1
BEFORE 106179390 94016050 110423650 95063770
AFTER 96473608 91054188 94936398 93198510
n=50
freeze 0 unfreeze 0 freeze 0 freeze 1
BEFORE 109506660 105643800 105970220 96948940
AFTER 105244651 97357482 97517358 88466266
n=100
freeze 0 unfreeze 0 freeze 0 freeze 1
BEFORE 127944210 122049330 120988900 101232850
AFTER 117298106 107034146 105696895 91977833
As shown above, after optimizations, it can save elapsed time.
By freezing 0 and subsequently freezing 1, the elapsed time is consistent,
indicating that my optimizations are highly effective.
---
v3:
- fix build warnings reported-by kernel test robot.
v2:
- open code inside the loop of cgroup_freeze instead of inline function.
- add helper to make code concise.
- remove selftest script(There are hierarchy test in test_freeze.c, I
think that is enough for this series).
Chen Ridong (3):
cgroup/freezer: Reduce redundant traversal for cgroup_freeze
cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper
cgroup/freezer: Reduce redundant propagation for
cgroup_propagate_frozen
include/linux/cgroup-defs.h | 6 +-
kernel/cgroup/freezer.c | 110 ++++++++++++++++++------------------
2 files changed, 59 insertions(+), 57 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze
2024-09-15 7:13 [PATHC v3 -next 0/3] Some optimizations about freezer Chen Ridong
@ 2024-09-15 7:13 ` Chen Ridong
2024-09-25 17:29 ` Michal Koutný
2024-09-15 7:13 ` [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper Chen Ridong
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Chen Ridong @ 2024-09-15 7:13 UTC (permalink / raw)
To: tj, lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro; +Cc: cgroups
Whether a cgroup is frozen is determined solely by whether it is set to
to be frozen and whether its parent is frozen. Currently, when is cgroup
is frozen or unfrozen, it iterates through the entire subtree to freeze
or unfreeze its descentdants. However, this is unesessary for a cgroup
that does not change its effective frozen status. This path aims to skip
the subtree if its parent does not have a change in effective freeze.
For an example, subtree like, a-b-c-d-e-f-g, when a is frozen, the
entire tree is frozen. If we freeze b and c again, it is unesessary to
iterate d, e, f and g. So does that If we unfreeze b/c.
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
include/linux/cgroup-defs.h | 2 +-
kernel/cgroup/freezer.c | 30 ++++++++++++++----------------
2 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 47ae4c4d924c..dd1ecab99eeb 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -397,7 +397,7 @@ struct cgroup_freezer_state {
bool freeze;
/* Should the cgroup actually be frozen? */
- int e_freeze;
+ bool e_freeze;
/* Fields below are protected by css_set_lock */
diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
index 617861a54793..188d5f2aeb5a 100644
--- a/kernel/cgroup/freezer.c
+++ b/kernel/cgroup/freezer.c
@@ -260,8 +260,10 @@ void cgroup_freezer_migrate_task(struct task_struct *task,
void cgroup_freeze(struct cgroup *cgrp, bool freeze)
{
struct cgroup_subsys_state *css;
+ struct cgroup *parent;
struct cgroup *dsct;
bool applied = false;
+ bool old_e;
lockdep_assert_held(&cgroup_mutex);
@@ -282,22 +284,18 @@ void cgroup_freeze(struct cgroup *cgrp, bool freeze)
if (cgroup_is_dead(dsct))
continue;
- if (freeze) {
- dsct->freezer.e_freeze++;
- /*
- * Already frozen because of ancestor's settings?
- */
- if (dsct->freezer.e_freeze > 1)
- continue;
- } else {
- dsct->freezer.e_freeze--;
- /*
- * Still frozen because of ancestor's settings?
- */
- if (dsct->freezer.e_freeze > 0)
- continue;
-
- WARN_ON_ONCE(dsct->freezer.e_freeze < 0);
+ /*
+ * e_freeze is affected by parent's e_freeze and dst's freeze.
+ * If old e_freeze eq new e_freeze, no change, its children
+ * will not be affected. So do nothing and skip the subtree
+ */
+ old_e = dsct->freezer.e_freeze;
+ parent = cgroup_parent(dsct);
+ dsct->freezer.e_freeze = (dsct->freezer.freeze ||
+ parent->freezer.e_freeze);
+ if (dsct->freezer.e_freeze == old_e) {
+ css = css_rightmost_descendant(css);
+ continue;
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper
2024-09-15 7:13 [PATHC v3 -next 0/3] Some optimizations about freezer Chen Ridong
2024-09-15 7:13 ` [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze Chen Ridong
@ 2024-09-15 7:13 ` Chen Ridong
2024-09-25 17:29 ` Michal Koutný
2024-09-15 7:13 ` [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen Chen Ridong
2024-09-23 3:37 ` [PATHC v3 -next 0/3] Some optimizations about freezer chenridong
3 siblings, 1 reply; 12+ messages in thread
From: Chen Ridong @ 2024-09-15 7:13 UTC (permalink / raw)
To: tj, lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro; +Cc: cgroups
Add help to update cgroup CGRP_FROZEN flag. Both cgroup_propagate_frozen
and cgroup_update_frozen functions update CGRP_FROZEN flag, this makes
code concise.
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
kernel/cgroup/freezer.c | 67 ++++++++++++++++++++---------------------
1 file changed, 32 insertions(+), 35 deletions(-)
diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
index 188d5f2aeb5a..bf1690a167dd 100644
--- a/kernel/cgroup/freezer.c
+++ b/kernel/cgroup/freezer.c
@@ -8,6 +8,28 @@
#include <trace/events/cgroup.h>
+/*
+ * Update CGRP_FROZEN of cgroup.flag
+ * Return true if flags is updated; false if flags has no change
+ */
+static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen)
+{
+ lockdep_assert_held(&css_set_lock);
+
+ /* Already there? */
+ if (test_bit(CGRP_FROZEN, &cgrp->flags) == frozen)
+ return false;
+
+ if (frozen)
+ set_bit(CGRP_FROZEN, &cgrp->flags);
+ else
+ clear_bit(CGRP_FROZEN, &cgrp->flags);
+
+ cgroup_file_notify(&cgrp->events_file);
+ TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen);
+ return true;
+}
+
/*
* Propagate the cgroup frozen state upwards by the cgroup tree.
*/
@@ -24,24 +46,16 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
while ((cgrp = cgroup_parent(cgrp))) {
if (frozen) {
cgrp->freezer.nr_frozen_descendants += desc;
- if (!test_bit(CGRP_FROZEN, &cgrp->flags) &&
- test_bit(CGRP_FREEZE, &cgrp->flags) &&
- cgrp->freezer.nr_frozen_descendants ==
- cgrp->nr_descendants) {
- set_bit(CGRP_FROZEN, &cgrp->flags);
- cgroup_file_notify(&cgrp->events_file);
- TRACE_CGROUP_PATH(notify_frozen, cgrp, 1);
- desc++;
- }
+ if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
+ (cgrp->freezer.nr_frozen_descendants !=
+ cgrp->nr_descendants))
+ continue;
} else {
cgrp->freezer.nr_frozen_descendants -= desc;
- if (test_bit(CGRP_FROZEN, &cgrp->flags)) {
- clear_bit(CGRP_FROZEN, &cgrp->flags);
- cgroup_file_notify(&cgrp->events_file);
- TRACE_CGROUP_PATH(notify_frozen, cgrp, 0);
- desc++;
- }
}
+
+ if (cgroup_update_frozen_flag(cgrp, frozen))
+ desc++;
}
}
@@ -53,8 +67,6 @@ void cgroup_update_frozen(struct cgroup *cgrp)
{
bool frozen;
- lockdep_assert_held(&css_set_lock);
-
/*
* If the cgroup has to be frozen (CGRP_FREEZE bit set),
* and all tasks are frozen and/or stopped, let's consider
@@ -63,24 +75,9 @@ void cgroup_update_frozen(struct cgroup *cgrp)
frozen = test_bit(CGRP_FREEZE, &cgrp->flags) &&
cgrp->freezer.nr_frozen_tasks == __cgroup_task_count(cgrp);
- if (frozen) {
- /* Already there? */
- if (test_bit(CGRP_FROZEN, &cgrp->flags))
- return;
-
- set_bit(CGRP_FROZEN, &cgrp->flags);
- } else {
- /* Already there? */
- if (!test_bit(CGRP_FROZEN, &cgrp->flags))
- return;
-
- clear_bit(CGRP_FROZEN, &cgrp->flags);
- }
- cgroup_file_notify(&cgrp->events_file);
- TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen);
-
- /* Update the state of ancestor cgroups. */
- cgroup_propagate_frozen(cgrp, frozen);
+ /* If flags is updated, update the state of ancestor cgroups. */
+ if (cgroup_update_frozen_flag(cgrp, frozen))
+ cgroup_propagate_frozen(cgrp, frozen);
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen
2024-09-15 7:13 [PATHC v3 -next 0/3] Some optimizations about freezer Chen Ridong
2024-09-15 7:13 ` [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze Chen Ridong
2024-09-15 7:13 ` [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper Chen Ridong
@ 2024-09-15 7:13 ` Chen Ridong
2024-09-25 17:46 ` Michal Koutný
2024-09-23 3:37 ` [PATHC v3 -next 0/3] Some optimizations about freezer chenridong
3 siblings, 1 reply; 12+ messages in thread
From: Chen Ridong @ 2024-09-15 7:13 UTC (permalink / raw)
To: tj, lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro; +Cc: cgroups
When a cgroup is frozen/unfrozen, it will always propagate bottom up.
However it is unnecessary to propagate to the top every time. This patch
aims to reduce redundant propagation for cgroup_propagate_frozen.
For example, subtree like:
a
|
b
/ | \
c d e
If c is frozen, and d and e are not frozen now, it doesn't have to
propagate to a; Only when c, d and e are all frozen, b and a could be set
to frozen. Therefore, if nr_frozen_descendants is not equal to
nr_descendants, just stop propagate. If a descendant is frozen, the
parent's nr_frozen_descendants add child->nr_descendants + 1. This can
reduce redundant propagation.
Additionally, cgroup_propagate_frozen is not only used to update the
ancestor state but also to update itself. This approach can make the code
clearer and significantly simplify cgroup_update_frozen.
Signed-off-by: Chen Ridong <chenridong@huawei.com>
---
include/linux/cgroup-defs.h | 4 +++-
kernel/cgroup/freezer.c | 29 +++++++++++++++++------------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index dd1ecab99eeb..41e4e5a7ae55 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -401,7 +401,9 @@ struct cgroup_freezer_state {
/* Fields below are protected by css_set_lock */
- /* Number of frozen descendant cgroups */
+ /* Aggregating frozen descendant cgroups, only when all
+ * descendants of a child are frozen will the count increase.
+ */
int nr_frozen_descendants;
/*
diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
index bf1690a167dd..4ee33198d6fb 100644
--- a/kernel/cgroup/freezer.c
+++ b/kernel/cgroup/freezer.c
@@ -35,27 +35,34 @@ static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen)
*/
static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
{
- int desc = 1;
-
+ int deta;
+ struct cgroup *parent;
/*
* If the new state is frozen, some freezing ancestor cgroups may change
* their state too, depending on if all their descendants are frozen.
*
* Otherwise, all ancestor cgroups are forced into the non-frozen state.
*/
- while ((cgrp = cgroup_parent(cgrp))) {
+ for (; cgrp; cgrp = cgroup_parent(cgrp)) {
if (frozen) {
- cgrp->freezer.nr_frozen_descendants += desc;
+ /* If freezer is not set, or cgrp has descendants
+ * that are not frozen, cgrp can't be frozen
+ */
if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
(cgrp->freezer.nr_frozen_descendants !=
- cgrp->nr_descendants))
- continue;
+ cgrp->nr_descendants))
+ break;
+ deta = cgrp->freezer.nr_frozen_descendants + 1;
} else {
- cgrp->freezer.nr_frozen_descendants -= desc;
+ deta = -(cgrp->freezer.nr_frozen_descendants + 1);
}
- if (cgroup_update_frozen_flag(cgrp, frozen))
- desc++;
+ /* No change, stop propagate */
+ if (!cgroup_update_frozen_flag(cgrp, frozen))
+ break;
+
+ parent = cgroup_parent(cgrp);
+ parent->freezer.nr_frozen_descendants += deta;
}
}
@@ -75,9 +82,7 @@ void cgroup_update_frozen(struct cgroup *cgrp)
frozen = test_bit(CGRP_FREEZE, &cgrp->flags) &&
cgrp->freezer.nr_frozen_tasks == __cgroup_task_count(cgrp);
- /* If flags is updated, update the state of ancestor cgroups. */
- if (cgroup_update_frozen_flag(cgrp, frozen))
- cgroup_propagate_frozen(cgrp, frozen);
+ cgroup_propagate_frozen(cgrp, frozen);
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 0/3] Some optimizations about freezer
2024-09-15 7:13 [PATHC v3 -next 0/3] Some optimizations about freezer Chen Ridong
` (2 preceding siblings ...)
2024-09-15 7:13 ` [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen Chen Ridong
@ 2024-09-23 3:37 ` chenridong
2024-09-23 15:36 ` Tejun Heo
3 siblings, 1 reply; 12+ messages in thread
From: chenridong @ 2024-09-23 3:37 UTC (permalink / raw)
To: tj, lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro; +Cc: cgroups
On 2024/9/15 15:13, Chen Ridong wrote:
> I optimized the freezer to reduce redundant loops, and I add helper
> to make code concise.
>
> The following subtree was tested to prove whether my optimizations are
> effective.
> 0
> / | \ \
> A B C 1
> / | \ \
> A B C 2
> .....
> n
> / | \
> A B C
>
> I tested by following steps:
> 1. freeze 0
> 2. unfreeze 0
> 3. freeze 0
> 4. freeze 1
>
> And I measured the elapsed time(ns).
>
> n=10
> freeze 0 unfreeze 0 freeze 0 freeze 1
> BEFORE 106179390 94016050 110423650 95063770
> AFTER 96473608 91054188 94936398 93198510
>
> n=50
> freeze 0 unfreeze 0 freeze 0 freeze 1
> BEFORE 109506660 105643800 105970220 96948940
> AFTER 105244651 97357482 97517358 88466266
>
> n=100
> freeze 0 unfreeze 0 freeze 0 freeze 1
> BEFORE 127944210 122049330 120988900 101232850
> AFTER 117298106 107034146 105696895 91977833
>
> As shown above, after optimizations, it can save elapsed time.
> By freezing 0 and subsequently freezing 1, the elapsed time is consistent,
> indicating that my optimizations are highly effective.
>
> ---
> v3:
> - fix build warnings reported-by kernel test robot.
>
> v2:
> - open code inside the loop of cgroup_freeze instead of inline function.
> - add helper to make code concise.
> - remove selftest script(There are hierarchy test in test_freeze.c, I
> think that is enough for this series).
>
> Chen Ridong (3):
> cgroup/freezer: Reduce redundant traversal for cgroup_freeze
> cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper
> cgroup/freezer: Reduce redundant propagation for
> cgroup_propagate_frozen
>
> include/linux/cgroup-defs.h | 6 +-
> kernel/cgroup/freezer.c | 110 ++++++++++++++++++------------------
> 2 files changed, 59 insertions(+), 57 deletions(-)
>
Friendly ping.
Best regards,
Ridong
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 0/3] Some optimizations about freezer
2024-09-23 3:37 ` [PATHC v3 -next 0/3] Some optimizations about freezer chenridong
@ 2024-09-23 15:36 ` Tejun Heo
2024-09-24 3:49 ` Chen Ridong
0 siblings, 1 reply; 12+ messages in thread
From: Tejun Heo @ 2024-09-23 15:36 UTC (permalink / raw)
To: chenridong
Cc: lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro,
cgroups
On Mon, Sep 23, 2024 at 11:37:14AM +0800, chenridong wrote:
> Friendly ping.
Will apply after the merge window.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 0/3] Some optimizations about freezer
2024-09-23 15:36 ` Tejun Heo
@ 2024-09-24 3:49 ` Chen Ridong
0 siblings, 0 replies; 12+ messages in thread
From: Chen Ridong @ 2024-09-24 3:49 UTC (permalink / raw)
To: Tejun Heo, chenridong
Cc: lizefan.x, hannes, longman, adityakali, sergeh, mkoutny, guro,
cgroups
On 2024/9/23 23:36, Tejun Heo wrote:
> On Mon, Sep 23, 2024 at 11:37:14AM +0800, chenridong wrote:
>> Friendly ping.
>
> Will apply after the merge window.
>
> Thanks.
>
Thank you.
Best regards,
Ridong
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze
2024-09-15 7:13 ` [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze Chen Ridong
@ 2024-09-25 17:29 ` Michal Koutný
0 siblings, 0 replies; 12+ messages in thread
From: Michal Koutný @ 2024-09-25 17:29 UTC (permalink / raw)
To: Chen Ridong
Cc: tj, lizefan.x, hannes, longman, adityakali, sergeh, guro, cgroups
[-- Attachment #1: Type: text/plain, Size: 359 bytes --]
On Sun, Sep 15, 2024 at 07:13:05AM GMT, Chen Ridong <chenridong@huawei.com> wrote:
> Signed-off-by: Chen Ridong <chenridong@huawei.com>
> ---
> include/linux/cgroup-defs.h | 2 +-
> kernel/cgroup/freezer.c | 30 ++++++++++++++----------------
> 2 files changed, 15 insertions(+), 17 deletions(-)
Reviewed-by: Michal Koutný <mkoutny@suse.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper
2024-09-15 7:13 ` [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper Chen Ridong
@ 2024-09-25 17:29 ` Michal Koutný
0 siblings, 0 replies; 12+ messages in thread
From: Michal Koutný @ 2024-09-25 17:29 UTC (permalink / raw)
To: Chen Ridong
Cc: tj, lizefan.x, hannes, longman, adityakali, sergeh, guro, cgroups
[-- Attachment #1: Type: text/plain, Size: 496 bytes --]
On Sun, Sep 15, 2024 at 07:13:06AM GMT, Chen Ridong <chenridong@huawei.com> wrote:
> Add help to update cgroup CGRP_FROZEN flag. Both cgroup_propagate_frozen
> and cgroup_update_frozen functions update CGRP_FROZEN flag, this makes
> code concise.
>
> Signed-off-by: Chen Ridong <chenridong@huawei.com>
> ---
> kernel/cgroup/freezer.c | 67 ++++++++++++++++++++---------------------
> 1 file changed, 32 insertions(+), 35 deletions(-)
Reviewed-by: Michal Koutný <mkoutny@suse.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen
2024-09-15 7:13 ` [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen Chen Ridong
@ 2024-09-25 17:46 ` Michal Koutný
2024-09-27 9:46 ` Chen Ridong
0 siblings, 1 reply; 12+ messages in thread
From: Michal Koutný @ 2024-09-25 17:46 UTC (permalink / raw)
To: Chen Ridong
Cc: tj, lizefan.x, hannes, longman, adityakali, sergeh, guro, cgroups
[-- Attachment #1: Type: text/plain, Size: 2948 bytes --]
On Sun, Sep 15, 2024 at 07:13:07AM GMT, Chen Ridong <chenridong@huawei.com> wrote:
> diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
> index dd1ecab99eeb..41e4e5a7ae55 100644
> --- a/include/linux/cgroup-defs.h
> +++ b/include/linux/cgroup-defs.h
> @@ -401,7 +401,9 @@ struct cgroup_freezer_state {
>
> /* Fields below are protected by css_set_lock */
>
> - /* Number of frozen descendant cgroups */
> + /* Aggregating frozen descendant cgroups, only when all
> + * descendants of a child are frozen will the count increase.
> + */
> int nr_frozen_descendants;
>
> /*
> diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
> index bf1690a167dd..4ee33198d6fb 100644
> --- a/kernel/cgroup/freezer.c
> +++ b/kernel/cgroup/freezer.c
> @@ -35,27 +35,34 @@ static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen)
> */
> static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
> {
> - int desc = 1;
> -
> + int deta;
delta
> + struct cgroup *parent;
I'd suggest here something like
/* root cgroup never changes freeze state */
if (WARN_ON(cgroup_parent(cgrp))
return;
so that the parent-> dereference below is explicitly safe.
> /*
> * If the new state is frozen, some freezing ancestor cgroups may change
> * their state too, depending on if all their descendants are frozen.
> *
> * Otherwise, all ancestor cgroups are forced into the non-frozen state.
> */
> - while ((cgrp = cgroup_parent(cgrp))) {
> + for (; cgrp; cgrp = cgroup_parent(cgrp)) {
> if (frozen) {
> - cgrp->freezer.nr_frozen_descendants += desc;
> + /* If freezer is not set, or cgrp has descendants
> + * that are not frozen, cgrp can't be frozen
> + */
> if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
> (cgrp->freezer.nr_frozen_descendants !=
> - cgrp->nr_descendants))
> - continue;
> + cgrp->nr_descendants))
> + break;
> + deta = cgrp->freezer.nr_frozen_descendants + 1;
> } else {
> - cgrp->freezer.nr_frozen_descendants -= desc;
> + deta = -(cgrp->freezer.nr_frozen_descendants + 1);
In this branch, if cgrp is unfrozen, delta = -1 is cgrp itself,
however is delta = -cgrp->freezer.nr_frozen_descendants warranted?
What if they are frozen empty children (of cgrp)? They likely shouldn't
be subtracted from ancestors nf_frozen_descendants.
(This refers to a situation when
C CGRP_FREEZE is set
|\
D E both CGRP_FREEZE is set
and an unfrozen task is migrated into C which would make C (temporarily)
unfrozen but not D nor E.)
> }
>
> - if (cgroup_update_frozen_flag(cgrp, frozen))
> - desc++;
> + /* No change, stop propagate */
> + if (!cgroup_update_frozen_flag(cgrp, frozen))
> + break;
> +
> + parent = cgroup_parent(cgrp);
> + parent->freezer.nr_frozen_descendants += deta;
Thanks,
Michal
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen
2024-09-25 17:46 ` Michal Koutný
@ 2024-09-27 9:46 ` Chen Ridong
2024-10-08 12:16 ` Chen Ridong
0 siblings, 1 reply; 12+ messages in thread
From: Chen Ridong @ 2024-09-27 9:46 UTC (permalink / raw)
To: Michal Koutný, Chen Ridong
Cc: tj, lizefan.x, hannes, longman, adityakali, sergeh, guro, cgroups
On 2024/9/26 1:46, Michal Koutný wrote:
> On Sun, Sep 15, 2024 at 07:13:07AM GMT, Chen Ridong <chenridong@huawei.com> wrote:
>> diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
>> index dd1ecab99eeb..41e4e5a7ae55 100644
>> --- a/include/linux/cgroup-defs.h
>> +++ b/include/linux/cgroup-defs.h
>> @@ -401,7 +401,9 @@ struct cgroup_freezer_state {
>>
>> /* Fields below are protected by css_set_lock */
>>
>> - /* Number of frozen descendant cgroups */
>> + /* Aggregating frozen descendant cgroups, only when all
>> + * descendants of a child are frozen will the count increase.
>> + */
>> int nr_frozen_descendants;
>>
>> /*
>> diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
>> index bf1690a167dd..4ee33198d6fb 100644
>> --- a/kernel/cgroup/freezer.c
>> +++ b/kernel/cgroup/freezer.c
>> @@ -35,27 +35,34 @@ static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen)
>> */
>> static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
>> {
>> - int desc = 1;
>> -
>> + int deta;
> delta
>
>> + struct cgroup *parent;
>
> I'd suggest here something like
>
> /* root cgroup never changes freeze state */
> if (WARN_ON(cgroup_parent(cgrp))
> return;
>
> so that the parent-> dereference below is explicitly safe.
>
>> /*
>> * If the new state is frozen, some freezing ancestor cgroups may change
>> * their state too, depending on if all their descendants are frozen.
>> *
>> * Otherwise, all ancestor cgroups are forced into the non-frozen state.
>> */
>> - while ((cgrp = cgroup_parent(cgrp))) {
>> + for (; cgrp; cgrp = cgroup_parent(cgrp)) {
>> if (frozen) {
>> - cgrp->freezer.nr_frozen_descendants += desc;
>> + /* If freezer is not set, or cgrp has descendants
>> + * that are not frozen, cgrp can't be frozen
>> + */
>> if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
>> (cgrp->freezer.nr_frozen_descendants !=
>> - cgrp->nr_descendants))
>> - continue;
>> + cgrp->nr_descendants))
>> + break;
>> + deta = cgrp->freezer.nr_frozen_descendants + 1;
>> } else {
>> - cgrp->freezer.nr_frozen_descendants -= desc;
>> + deta = -(cgrp->freezer.nr_frozen_descendants + 1);
>
> In this branch, if cgrp is unfrozen, delta = -1 is cgrp itself,
> however is delta = -cgrp->freezer.nr_frozen_descendants warranted?
> What if they are frozen empty children (of cgrp)? They likely shouldn't
> be subtracted from ancestors nf_frozen_descendants.
>
> (This refers to a situation when
>
> C CGRP_FREEZE is set
> |\
> D E both CGRP_FREEZE is set
>
> and an unfrozen task is migrated into C which would make C (temporarily)
> unfrozen but not D nor E.)
>
Thank you, Michal.
I sorry I missed this situation.
If unfreezing a cgroup, it seems it has to propagate to the top.
After consideration, I modify this function.
the following is acceptable?
/*
* Propagate the cgroup frozen state upwards by the cgroup tree.
*/
static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
{
int deta = 0;
struct cgroup *parent;
/*
* case1: If the new state is frozen, some freezing ancestor cgroups
may change
* their state too, depending on if all their descendants are frozen.
*
* case2: unfrozen, all ancestor cgroups are forced into the non-frozen
state.
*/
for (; cgrp; cgrp = cgroup_parent(cgrp)) {
if (frozen) {
/* If freezer is not set, or cgrp has descendants
* that are not frozen, cgrp can't be frozen
*/
if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
(cgrp->freezer.nr_frozen_descendants !=
cgrp->nr_descendants))
break;
/* No change, stop propagate */
if (!cgroup_update_frozen_flag(cgrp, frozen))
break;
deta = cgrp->freezer.nr_frozen_descendants + 1;
} else {
/* case2: have to propagate all ancestor */
if (cgroup_update_frozen_flag(cgrp, frozen))
deta++;
}
parent = cgroup_parent(cgrp);
parent->freezer.nr_frozen_descendants += deta;
}
}
Best regards,
Ridong
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen
2024-09-27 9:46 ` Chen Ridong
@ 2024-10-08 12:16 ` Chen Ridong
0 siblings, 0 replies; 12+ messages in thread
From: Chen Ridong @ 2024-10-08 12:16 UTC (permalink / raw)
To: Michal Koutný, Chen Ridong
Cc: tj, lizefan.x, hannes, longman, adityakali, sergeh, guro, cgroups
On 2024/9/27 17:46, Chen Ridong wrote:
>
>
> On 2024/9/26 1:46, Michal Koutný wrote:
>> On Sun, Sep 15, 2024 at 07:13:07AM GMT, Chen Ridong
>> <chenridong@huawei.com> wrote:
>>> diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
>>> index dd1ecab99eeb..41e4e5a7ae55 100644
>>> --- a/include/linux/cgroup-defs.h
>>> +++ b/include/linux/cgroup-defs.h
>>> @@ -401,7 +401,9 @@ struct cgroup_freezer_state {
>>> /* Fields below are protected by css_set_lock */
>>> - /* Number of frozen descendant cgroups */
>>> + /* Aggregating frozen descendant cgroups, only when all
>>> + * descendants of a child are frozen will the count increase.
>>> + */
>>> int nr_frozen_descendants;
>>> /*
>>> diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
>>> index bf1690a167dd..4ee33198d6fb 100644
>>> --- a/kernel/cgroup/freezer.c
>>> +++ b/kernel/cgroup/freezer.c
>>> @@ -35,27 +35,34 @@ static bool cgroup_update_frozen_flag(struct
>>> cgroup *cgrp, bool frozen)
>>> */
>>> static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
>>> {
>>> - int desc = 1;
>>> -
>>> + int deta;
>> delta
>>
>>> + struct cgroup *parent;
>>
>> I'd suggest here something like
>>
>> /* root cgroup never changes freeze state */
>> if (WARN_ON(cgroup_parent(cgrp))
>> return;
>>
>> so that the parent-> dereference below is explicitly safe.
>>
>>> /*
>>> * If the new state is frozen, some freezing ancestor cgroups
>>> may change
>>> * their state too, depending on if all their descendants are
>>> frozen.
>>> *
>>> * Otherwise, all ancestor cgroups are forced into the
>>> non-frozen state.
>>> */
>>> - while ((cgrp = cgroup_parent(cgrp))) {
>>> + for (; cgrp; cgrp = cgroup_parent(cgrp)) {
>>> if (frozen) {
>>> - cgrp->freezer.nr_frozen_descendants += desc;
>>> + /* If freezer is not set, or cgrp has descendants
>>> + * that are not frozen, cgrp can't be frozen
>>> + */
>>> if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
>>> (cgrp->freezer.nr_frozen_descendants !=
>>> - cgrp->nr_descendants))
>>> - continue;
>>> + cgrp->nr_descendants))
>>> + break;
>>> + deta = cgrp->freezer.nr_frozen_descendants + 1;
>>> } else {
>>> - cgrp->freezer.nr_frozen_descendants -= desc;
>>> + deta = -(cgrp->freezer.nr_frozen_descendants + 1);
>>
>> In this branch, if cgrp is unfrozen, delta = -1 is cgrp itself,
>> however is delta = -cgrp->freezer.nr_frozen_descendants warranted?
>> What if they are frozen empty children (of cgrp)? They likely shouldn't
>> be subtracted from ancestors nf_frozen_descendants.
>>
>> (This refers to a situation when
>>
>> C CGRP_FREEZE is set
>> |\
>> D E both CGRP_FREEZE is set
>>
>> and an unfrozen task is migrated into C which would make C (temporarily)
>> unfrozen but not D nor E.)
>>
> Thank you, Michal.
>
> I sorry I missed this situation.
> If unfreezing a cgroup, it seems it has to propagate to the top.
>
> After consideration, I modify this function.
> the following is acceptable?
>
> /*
> * Propagate the cgroup frozen state upwards by the cgroup tree.
> */
> static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
> {
> int deta = 0;
> struct cgroup *parent;
> /*
> * case1: If the new state is frozen, some freezing ancestor
> cgroups may change
> * their state too, depending on if all their descendants are frozen.
> *
> * case2: unfrozen, all ancestor cgroups are forced into the
> non-frozen state.
> */
> for (; cgrp; cgrp = cgroup_parent(cgrp)) {
> if (frozen) {
> /* If freezer is not set, or cgrp has descendants
> * that are not frozen, cgrp can't be frozen
> */
> if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
> (cgrp->freezer.nr_frozen_descendants !=
> cgrp->nr_descendants))
> break;
> /* No change, stop propagate */
> if (!cgroup_update_frozen_flag(cgrp, frozen))
> break;
> deta = cgrp->freezer.nr_frozen_descendants + 1;
> } else {
> /* case2: have to propagate all ancestor */
> if (cgroup_update_frozen_flag(cgrp, frozen))
> deta++;
> }
>
> parent = cgroup_parent(cgrp);
> parent->freezer.nr_frozen_descendants += deta;
> }
> }
>
> Best regards,
> Ridong
>
Hi, Michal, Do you think this can be acceptable?
I don't have a better idea, If you have a better a idea, please let me know.
Best regards,
Ridong
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-10-08 12:16 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-15 7:13 [PATHC v3 -next 0/3] Some optimizations about freezer Chen Ridong
2024-09-15 7:13 ` [PATHC v3 -next 1/3] cgroup/freezer: Reduce redundant traversal for cgroup_freeze Chen Ridong
2024-09-25 17:29 ` Michal Koutný
2024-09-15 7:13 ` [PATHC v3 -next 2/3] cgroup/freezer: Add cgroup CGRP_FROZEN flag update helper Chen Ridong
2024-09-25 17:29 ` Michal Koutný
2024-09-15 7:13 ` [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen Chen Ridong
2024-09-25 17:46 ` Michal Koutný
2024-09-27 9:46 ` Chen Ridong
2024-10-08 12:16 ` Chen Ridong
2024-09-23 3:37 ` [PATHC v3 -next 0/3] Some optimizations about freezer chenridong
2024-09-23 15:36 ` Tejun Heo
2024-09-24 3:49 ` Chen Ridong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox