From: Tejun Heo <tj@kernel.org>
To: lizefan@huawei.com, hannes@cmpxchg.org
Cc: cgroups@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel-team@fb.com, Tejun Heo <tj@kernel.org>
Subject: [PATCH 10/12] cgroup: introduce cgroup_{save|propagate|restore}_control()
Date: Mon, 22 Feb 2016 22:45:44 -0500 [thread overview]
Message-ID: <1456199146-14765-11-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1456199146-14765-1-git-send-email-tj@kernel.org>
While controllers are being enabled and disabled in
cgroup_subtree_control_write(), the original subsystem masks are
stashed in local variables so that they can be restored if the
operation fails in the middle.
This patch adds dedicated fields to struct cgroup to be used instead
of the local variables and implements functions to stash the current
values, propagate the changes and restore them recursively. Combined
with the previous changes, this makes subsystem management operations
fully recursive and modularlized. This will be used to expand cgroup
core functionalities.
While at it, remove now unused @css_enable and @css_disable from
cgroup_subtree_control_write().
Signed-off-by: Tejun Heo <tj@kernel.org>
---
include/linux/cgroup-defs.h | 2 ++
kernel/cgroup.c | 82 ++++++++++++++++++++++++++++++++++-----------
2 files changed, 64 insertions(+), 20 deletions(-)
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 13a2708..b1351d1 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -260,6 +260,8 @@ struct cgroup {
*/
u16 subtree_control;
u16 subtree_ss_mask;
+ u16 old_subtree_control;
+ u16 old_subtree_ss_mask;
/* Private pointers for each registered subsystem */
struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index d8c8eb2..86d7bcb 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -3027,6 +3027,62 @@ static bool cgroup_drain_offline(struct cgroup *cgrp)
}
/**
+ * cgroup_save_control - save control masks of a subtree
+ * @cgrp: root of the target subtree
+ *
+ * Save ->subtree_control and ->subtree_ss_mask to the respective old_
+ * prefixed fields for @cgrp's subtree including @cgrp itself.
+ */
+static void cgroup_save_control(struct cgroup *cgrp)
+{
+ struct cgroup *dsct;
+ struct cgroup_subsys_state *d_css;
+
+ cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) {
+ dsct->old_subtree_control = dsct->subtree_control;
+ dsct->old_subtree_ss_mask = dsct->subtree_ss_mask;
+ }
+}
+
+/**
+ * cgroup_propagate_control - refresh control masks of a subtree
+ * @cgrp: root of the target subtree
+ *
+ * For @cgrp and its subtree, ensure ->subtree_ss_mask matches
+ * ->subtree_control and propagate controller availability through the
+ * subtree so that descendants don't have unavailable controllers enabled.
+ */
+static void cgroup_propagate_control(struct cgroup *cgrp)
+{
+ struct cgroup *dsct;
+ struct cgroup_subsys_state *d_css;
+
+ cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) {
+ dsct->subtree_control &= cgroup_control(dsct);
+ dsct->subtree_ss_mask = cgroup_calc_subtree_ss_mask(dsct,
+ dsct->subtree_control);
+ }
+}
+
+/**
+ * cgroup_restore_control - restore control masks of a subtree
+ * @cgrp: root of the target subtree
+ *
+ * Restore ->subtree_control and ->subtree_ss_mask from the respective old_
+ * prefixed fields for @cgrp's subtree including @cgrp itself.
+ */
+static void cgroup_restore_control(struct cgroup *cgrp)
+{
+ struct cgroup *dsct;
+ struct cgroup_subsys_state *d_css;
+
+ cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) {
+ dsct->subtree_control = dsct->old_subtree_control;
+ dsct->subtree_ss_mask = dsct->old_subtree_ss_mask;
+ }
+}
+
+/**
* cgroup_apply_control_enable - enable or show csses according to control
* @cgrp: root of the target subtree
*
@@ -3114,7 +3170,6 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
loff_t off)
{
u16 enable = 0, disable = 0;
- u16 css_enable, css_disable, old_sc, new_sc, old_ss, new_ss;
struct cgroup *cgrp, *child;
struct cgroup_subsys *ss;
char *tok;
@@ -3201,25 +3256,14 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
return restart_syscall();
}
- /*
- * Update subsys masks and calculate what needs to be done. More
- * subsystems than specified may need to be enabled or disabled
- * depending on subsystem dependencies.
- */
- old_sc = cgrp->subtree_control;
- old_ss = cgrp->subtree_ss_mask;
- new_sc = (old_sc | enable) & ~disable;
- new_ss = cgroup_calc_subtree_ss_mask(cgrp, new_sc);
+ /* save and update control masks and prepare csses */
+ cgroup_save_control(cgrp);
- css_enable = ~old_ss & new_ss;
- css_disable = old_ss & ~new_ss;
- enable |= css_enable;
- disable |= css_disable;
+ cgrp->subtree_control |= enable;
+ cgrp->subtree_control &= ~disable;
- cgrp->subtree_control = new_sc;
- cgrp->subtree_ss_mask = new_ss;
+ cgroup_propagate_control(cgrp);
- /* prepare csses */
ret = cgroup_apply_control_enable(cgrp);
if (ret)
goto err_undo_css;
@@ -3244,9 +3288,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
err_undo_css:
/* restore masks and shoot down new csses */
- cgrp->subtree_control = old_sc;
- cgrp->subtree_ss_mask = old_ss;
-
+ cgroup_restore_control(cgrp);
cgroup_apply_control_disable(cgrp);
goto out_unlock;
--
2.5.0
next prev parent reply other threads:[~2016-02-23 3:45 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-23 3:45 [PATCHSET cgroup/for-4.6] cgroup: make control mask updates modular and recursive Tejun Heo
2016-02-23 3:45 ` [PATCH 01/12] cgroup: separate out interface file creation from css creation Tejun Heo
2016-02-23 3:45 ` [PATCH 02/12] cgroup: explicitly track whether a cgroup_subsys_state is visible to userland Tejun Heo
2016-02-23 3:45 ` [PATCH 03/12] cgroup: reorder operations in cgroup_mkdir() Tejun Heo
2016-02-23 3:45 ` [PATCH 04/12] cgroup: factor out cgroup_create() out of cgroup_mkdir() Tejun Heo
2016-02-23 3:45 ` [PATCH 05/12] cgroup: introduce cgroup_control() and cgroup_ss_mask() Tejun Heo
2016-02-23 3:45 ` [PATCH 06/12] cgroup: factor out cgroup_drain_offline() from cgroup_subtree_control_write() Tejun Heo
[not found] ` <1456199146-14765-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2016-02-23 3:45 ` [PATCH 07/12] cgroup: factor out cgroup_apply_control_disable() " Tejun Heo
2016-02-23 3:45 ` [PATCH 08/12] cgroup: factor out cgroup_apply_control_enable() " Tejun Heo
2016-02-23 3:45 ` [PATCH 11/12] cgroup: Factor out cgroup_{apply|finalize}_control() " Tejun Heo
2016-02-23 3:45 ` [PATCH 09/12] cgroup: make cgroup_drain_offline() and cgroup_apply_control_{disable|enable}() recursive Tejun Heo
2016-02-23 3:45 ` Tejun Heo [this message]
2016-02-23 3:45 ` [PATCH 12/12] cgroup: make cgroup_calc_subtree_ss_mask() take @this_ss_mask Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1456199146-14765-11-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=cgroups@vger.kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kernel-team@fb.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).