cgroup: update cgroup->subsys_mask to ->child_subsys_mask and restore cgroup_root->subsys_mask
944196278d
("cgroup: move ->subsys_mask from cgroupfs_root to
cgroup") moved ->subsys_mask from cgroup_root to cgroup to prepare for
the unified hierarhcy; however, it turns out that carrying the
subsys_mask of the children in the parent, instead of itself, is a lot
more natural. This patch restores cgroup_root->subsys_mask and morphs
cgroup->subsys_mask into cgroup->child_subsys_mask.
* Uses of root->cgrp.subsys_mask are restored to root->subsys_mask.
* Remove automatic setting and clearing of cgrp->subsys_mask and
instead just inherit ->child_subsys_mask from the parent during
cgroup creation. Note that this doesn't affect any current
behaviors.
* Undo __kill_css() separation.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
This commit is contained in:
Родитель
ea8fd3b47f
Коммит
f392e51cd6
|
@ -173,8 +173,8 @@ struct cgroup {
|
||||||
*/
|
*/
|
||||||
u64 serial_nr;
|
u64 serial_nr;
|
||||||
|
|
||||||
/* The bitmask of subsystems attached to this cgroup */
|
/* the bitmask of subsystems enabled on the child cgroups */
|
||||||
unsigned long subsys_mask;
|
unsigned long child_subsys_mask;
|
||||||
|
|
||||||
/* Private pointers for each registered subsystem */
|
/* Private pointers for each registered subsystem */
|
||||||
struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
|
struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
|
||||||
|
@ -282,6 +282,9 @@ enum {
|
||||||
struct cgroup_root {
|
struct cgroup_root {
|
||||||
struct kernfs_root *kf_root;
|
struct kernfs_root *kf_root;
|
||||||
|
|
||||||
|
/* The bitmask of subsystems attached to this hierarchy */
|
||||||
|
unsigned long subsys_mask;
|
||||||
|
|
||||||
/* Unique id for this hierarchy. */
|
/* Unique id for this hierarchy. */
|
||||||
int hierarchy_id;
|
int hierarchy_id;
|
||||||
|
|
||||||
|
|
|
@ -529,7 +529,7 @@ static struct css_set *find_existing_css_set(struct css_set *old_cset,
|
||||||
* won't change, so no need for locking.
|
* won't change, so no need for locking.
|
||||||
*/
|
*/
|
||||||
for_each_subsys(ss, i) {
|
for_each_subsys(ss, i) {
|
||||||
if (root->cgrp.subsys_mask & (1UL << i)) {
|
if (root->subsys_mask & (1UL << i)) {
|
||||||
/* Subsystem is in this hierarchy. So we want
|
/* Subsystem is in this hierarchy. So we want
|
||||||
* the subsystem state from the new
|
* the subsystem state from the new
|
||||||
* cgroup */
|
* cgroup */
|
||||||
|
@ -742,7 +742,7 @@ static void cgroup_destroy_root(struct cgroup_root *root)
|
||||||
BUG_ON(!list_empty(&cgrp->children));
|
BUG_ON(!list_empty(&cgrp->children));
|
||||||
|
|
||||||
/* Rebind all subsystems back to the default hierarchy */
|
/* Rebind all subsystems back to the default hierarchy */
|
||||||
rebind_subsystems(&cgrp_dfl_root, cgrp->subsys_mask);
|
rebind_subsystems(&cgrp_dfl_root, root->subsys_mask);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release all the links from cset_links to this hierarchy's
|
* Release all the links from cset_links to this hierarchy's
|
||||||
|
@ -1050,8 +1050,11 @@ static int rebind_subsystems(struct cgroup_root *dst_root,
|
||||||
ss->root = dst_root;
|
ss->root = dst_root;
|
||||||
css->cgroup = &dst_root->cgrp;
|
css->cgroup = &dst_root->cgrp;
|
||||||
|
|
||||||
src_root->cgrp.subsys_mask &= ~(1 << ssid);
|
src_root->subsys_mask &= ~(1 << ssid);
|
||||||
dst_root->cgrp.subsys_mask |= 1 << ssid;
|
src_root->cgrp.child_subsys_mask &= ~(1 << ssid);
|
||||||
|
|
||||||
|
dst_root->subsys_mask |= 1 << ssid;
|
||||||
|
dst_root->cgrp.child_subsys_mask |= 1 << ssid;
|
||||||
|
|
||||||
if (ss->bind)
|
if (ss->bind)
|
||||||
ss->bind(css);
|
ss->bind(css);
|
||||||
|
@ -1069,7 +1072,7 @@ static int cgroup_show_options(struct seq_file *seq,
|
||||||
int ssid;
|
int ssid;
|
||||||
|
|
||||||
for_each_subsys(ss, ssid)
|
for_each_subsys(ss, ssid)
|
||||||
if (root->cgrp.subsys_mask & (1 << ssid))
|
if (root->subsys_mask & (1 << ssid))
|
||||||
seq_printf(seq, ",%s", ss->name);
|
seq_printf(seq, ",%s", ss->name);
|
||||||
if (root->flags & CGRP_ROOT_SANE_BEHAVIOR)
|
if (root->flags & CGRP_ROOT_SANE_BEHAVIOR)
|
||||||
seq_puts(seq, ",sane_behavior");
|
seq_puts(seq, ",sane_behavior");
|
||||||
|
@ -1273,12 +1276,12 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
if (opts.subsys_mask != root->cgrp.subsys_mask || opts.release_agent)
|
if (opts.subsys_mask != root->subsys_mask || opts.release_agent)
|
||||||
pr_warning("cgroup: option changes via remount are deprecated (pid=%d comm=%s)\n",
|
pr_warning("cgroup: option changes via remount are deprecated (pid=%d comm=%s)\n",
|
||||||
task_tgid_nr(current), current->comm);
|
task_tgid_nr(current), current->comm);
|
||||||
|
|
||||||
added_mask = opts.subsys_mask & ~root->cgrp.subsys_mask;
|
added_mask = opts.subsys_mask & ~root->subsys_mask;
|
||||||
removed_mask = root->cgrp.subsys_mask & ~opts.subsys_mask;
|
removed_mask = root->subsys_mask & ~opts.subsys_mask;
|
||||||
|
|
||||||
/* Don't allow flags or name to change at remount */
|
/* Don't allow flags or name to change at remount */
|
||||||
if (((opts.flags ^ root->flags) & CGRP_ROOT_OPTION_MASK) ||
|
if (((opts.flags ^ root->flags) & CGRP_ROOT_OPTION_MASK) ||
|
||||||
|
@ -1535,7 +1538,7 @@ retry:
|
||||||
* subsystems) then they must match.
|
* subsystems) then they must match.
|
||||||
*/
|
*/
|
||||||
if ((opts.subsys_mask || opts.none) &&
|
if ((opts.subsys_mask || opts.none) &&
|
||||||
(opts.subsys_mask != root->cgrp.subsys_mask)) {
|
(opts.subsys_mask != root->subsys_mask)) {
|
||||||
if (!name_match)
|
if (!name_match)
|
||||||
continue;
|
continue;
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -3658,8 +3661,6 @@ static int create_css(struct cgroup *cgrp, struct cgroup_subsys *ss)
|
||||||
cgroup_get(cgrp);
|
cgroup_get(cgrp);
|
||||||
css_get(css->parent);
|
css_get(css->parent);
|
||||||
|
|
||||||
cgrp->subsys_mask |= 1 << ss->id;
|
|
||||||
|
|
||||||
if (ss->broken_hierarchy && !ss->warned_broken_hierarchy &&
|
if (ss->broken_hierarchy && !ss->warned_broken_hierarchy &&
|
||||||
parent->parent) {
|
parent->parent) {
|
||||||
pr_warning("cgroup: %s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n",
|
pr_warning("cgroup: %s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n",
|
||||||
|
@ -3780,13 +3781,15 @@ static long cgroup_create(struct cgroup *parent, const char *name,
|
||||||
|
|
||||||
/* let's create and online css's */
|
/* let's create and online css's */
|
||||||
for_each_subsys(ss, ssid) {
|
for_each_subsys(ss, ssid) {
|
||||||
if (root->cgrp.subsys_mask & (1 << ssid)) {
|
if (parent->child_subsys_mask & (1 << ssid)) {
|
||||||
err = create_css(cgrp, ss);
|
err = create_css(cgrp, ss);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_destroy;
|
goto err_destroy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cgrp->child_subsys_mask = parent->child_subsys_mask;
|
||||||
|
|
||||||
kernfs_activate(kn);
|
kernfs_activate(kn);
|
||||||
|
|
||||||
mutex_unlock(&cgroup_mutex);
|
mutex_unlock(&cgroup_mutex);
|
||||||
|
@ -3882,7 +3885,16 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
|
||||||
queue_work(cgroup_destroy_wq, &css->destroy_work);
|
queue_work(cgroup_destroy_wq, &css->destroy_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __kill_css(struct cgroup_subsys_state *css)
|
/**
|
||||||
|
* kill_css - destroy a css
|
||||||
|
* @css: css to destroy
|
||||||
|
*
|
||||||
|
* This function initiates destruction of @css by removing cgroup interface
|
||||||
|
* files and putting its base reference. ->css_offline() will be invoked
|
||||||
|
* asynchronously once css_tryget() is guaranteed to fail and when the
|
||||||
|
* reference count reaches zero, @css will be released.
|
||||||
|
*/
|
||||||
|
static void kill_css(struct cgroup_subsys_state *css)
|
||||||
{
|
{
|
||||||
lockdep_assert_held(&cgroup_tree_mutex);
|
lockdep_assert_held(&cgroup_tree_mutex);
|
||||||
|
|
||||||
|
@ -3911,28 +3923,6 @@ static void __kill_css(struct cgroup_subsys_state *css)
|
||||||
percpu_ref_kill_and_confirm(&css->refcnt, css_killed_ref_fn);
|
percpu_ref_kill_and_confirm(&css->refcnt, css_killed_ref_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* kill_css - destroy a css
|
|
||||||
* @css: css to destroy
|
|
||||||
*
|
|
||||||
* This function initiates destruction of @css by removing cgroup interface
|
|
||||||
* files and putting its base reference. ->css_offline() will be invoked
|
|
||||||
* asynchronously once css_tryget() is guaranteed to fail and when the
|
|
||||||
* reference count reaches zero, @css will be released.
|
|
||||||
*/
|
|
||||||
static void kill_css(struct cgroup_subsys_state *css)
|
|
||||||
{
|
|
||||||
struct cgroup *cgrp = css->cgroup;
|
|
||||||
|
|
||||||
lockdep_assert_held(&cgroup_tree_mutex);
|
|
||||||
|
|
||||||
/* if already killed, noop */
|
|
||||||
if (cgrp->subsys_mask & (1 << css->ss->id)) {
|
|
||||||
cgrp->subsys_mask &= ~(1 << css->ss->id);
|
|
||||||
__kill_css(css);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cgroup_destroy_locked - the first stage of cgroup destruction
|
* cgroup_destroy_locked - the first stage of cgroup destruction
|
||||||
* @cgrp: cgroup to be destroyed
|
* @cgrp: cgroup to be destroyed
|
||||||
|
@ -4145,7 +4135,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
|
||||||
|
|
||||||
BUG_ON(online_css(css));
|
BUG_ON(online_css(css));
|
||||||
|
|
||||||
cgrp_dfl_root.cgrp.subsys_mask |= 1 << ss->id;
|
cgrp_dfl_root.subsys_mask |= 1 << ss->id;
|
||||||
|
|
||||||
mutex_unlock(&cgroup_mutex);
|
mutex_unlock(&cgroup_mutex);
|
||||||
mutex_unlock(&cgroup_tree_mutex);
|
mutex_unlock(&cgroup_tree_mutex);
|
||||||
|
@ -4302,7 +4292,7 @@ int proc_cgroup_show(struct seq_file *m, void *v)
|
||||||
|
|
||||||
seq_printf(m, "%d:", root->hierarchy_id);
|
seq_printf(m, "%d:", root->hierarchy_id);
|
||||||
for_each_subsys(ss, ssid)
|
for_each_subsys(ss, ssid)
|
||||||
if (root->cgrp.subsys_mask & (1 << ssid))
|
if (root->subsys_mask & (1 << ssid))
|
||||||
seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
|
seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
|
||||||
if (strlen(root->name))
|
if (strlen(root->name))
|
||||||
seq_printf(m, "%sname=%s", count ? "," : "",
|
seq_printf(m, "%sname=%s", count ? "," : "",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче