|
@@ -189,7 +189,7 @@ static u16 have_canfork_callback __read_mostly;
|
|
|
|
|
|
/* cgroup namespace for init task */
|
|
|
struct cgroup_namespace init_cgroup_ns = {
|
|
|
- .count = { .counter = 2, },
|
|
|
+ .count = REFCOUNT_INIT(2),
|
|
|
.user_ns = &init_user_ns,
|
|
|
.ns.ops = &cgroupns_operations,
|
|
|
.ns.inum = PROC_CGROUP_INIT_INO,
|
|
@@ -436,7 +436,12 @@ out_unlock:
|
|
|
return css;
|
|
|
}
|
|
|
|
|
|
-static void cgroup_get(struct cgroup *cgrp)
|
|
|
+static void __maybe_unused cgroup_get(struct cgroup *cgrp)
|
|
|
+{
|
|
|
+ css_get(&cgrp->self);
|
|
|
+}
|
|
|
+
|
|
|
+static void cgroup_get_live(struct cgroup *cgrp)
|
|
|
{
|
|
|
WARN_ON_ONCE(cgroup_is_dead(cgrp));
|
|
|
css_get(&cgrp->self);
|
|
@@ -554,7 +559,7 @@ EXPORT_SYMBOL_GPL(of_css);
|
|
|
* haven't been created.
|
|
|
*/
|
|
|
struct css_set init_css_set = {
|
|
|
- .refcount = ATOMIC_INIT(1),
|
|
|
+ .refcount = REFCOUNT_INIT(1),
|
|
|
.tasks = LIST_HEAD_INIT(init_css_set.tasks),
|
|
|
.mg_tasks = LIST_HEAD_INIT(init_css_set.mg_tasks),
|
|
|
.task_iters = LIST_HEAD_INIT(init_css_set.task_iters),
|
|
@@ -724,7 +729,7 @@ void put_css_set_locked(struct css_set *cset)
|
|
|
|
|
|
lockdep_assert_held(&css_set_lock);
|
|
|
|
|
|
- if (!atomic_dec_and_test(&cset->refcount))
|
|
|
+ if (!refcount_dec_and_test(&cset->refcount))
|
|
|
return;
|
|
|
|
|
|
/* This css_set is dead. unlink it and release cgroup and css refs */
|
|
@@ -932,7 +937,7 @@ static void link_css_set(struct list_head *tmp_links, struct css_set *cset,
|
|
|
list_add_tail(&link->cgrp_link, &cset->cgrp_links);
|
|
|
|
|
|
if (cgroup_parent(cgrp))
|
|
|
- cgroup_get(cgrp);
|
|
|
+ cgroup_get_live(cgrp);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -977,7 +982,7 @@ static struct css_set *find_css_set(struct css_set *old_cset,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- atomic_set(&cset->refcount, 1);
|
|
|
+ refcount_set(&cset->refcount, 1);
|
|
|
INIT_LIST_HEAD(&cset->tasks);
|
|
|
INIT_LIST_HEAD(&cset->mg_tasks);
|
|
|
INIT_LIST_HEAD(&cset->task_iters);
|
|
@@ -1640,7 +1645,7 @@ void init_cgroup_root(struct cgroup_root *root, struct cgroup_sb_opts *opts)
|
|
|
set_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->cgrp.flags);
|
|
|
}
|
|
|
|
|
|
-int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
|
|
|
+int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask, int ref_flags)
|
|
|
{
|
|
|
LIST_HEAD(tmp_links);
|
|
|
struct cgroup *root_cgrp = &root->cgrp;
|
|
@@ -1656,8 +1661,8 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
|
|
|
root_cgrp->id = ret;
|
|
|
root_cgrp->ancestor_ids[0] = ret;
|
|
|
|
|
|
- ret = percpu_ref_init(&root_cgrp->self.refcnt, css_release, 0,
|
|
|
- GFP_KERNEL);
|
|
|
+ ret = percpu_ref_init(&root_cgrp->self.refcnt, css_release,
|
|
|
+ ref_flags, GFP_KERNEL);
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
@@ -1802,7 +1807,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
}
|
|
|
cgrp_dfl_visible = true;
|
|
|
- cgroup_get(&cgrp_dfl_root.cgrp);
|
|
|
+ cgroup_get_live(&cgrp_dfl_root.cgrp);
|
|
|
|
|
|
dentry = cgroup_do_mount(&cgroup2_fs_type, flags, &cgrp_dfl_root,
|
|
|
CGROUP2_SUPER_MAGIC, ns);
|
|
@@ -2576,7 +2581,7 @@ restart:
|
|
|
if (!css || !percpu_ref_is_dying(&css->refcnt))
|
|
|
continue;
|
|
|
|
|
|
- cgroup_get(dsct);
|
|
|
+ cgroup_get_live(dsct);
|
|
|
prepare_to_wait(&dsct->offline_waitq, &wait,
|
|
|
TASK_UNINTERRUPTIBLE);
|
|
|
|
|
@@ -3947,7 +3952,7 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
|
|
|
{
|
|
|
lockdep_assert_held(&cgroup_mutex);
|
|
|
|
|
|
- cgroup_get(cgrp);
|
|
|
+ cgroup_get_live(cgrp);
|
|
|
|
|
|
memset(css, 0, sizeof(*css));
|
|
|
css->cgroup = cgrp;
|
|
@@ -4123,7 +4128,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
|
|
|
/* allocation complete, commit to creation */
|
|
|
list_add_tail_rcu(&cgrp->self.sibling, &cgroup_parent(cgrp)->self.children);
|
|
|
atomic_inc(&root->nr_cgrps);
|
|
|
- cgroup_get(parent);
|
|
|
+ cgroup_get_live(parent);
|
|
|
|
|
|
/*
|
|
|
* @cgrp is now fully operational. If something fails after this
|
|
@@ -4513,7 +4518,7 @@ int __init cgroup_init(void)
|
|
|
hash_add(css_set_table, &init_css_set.hlist,
|
|
|
css_set_hash(init_css_set.subsys));
|
|
|
|
|
|
- BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0));
|
|
|
+ BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0, 0));
|
|
|
|
|
|
mutex_unlock(&cgroup_mutex);
|
|
|
|
|
@@ -4947,7 +4952,7 @@ struct cgroup *cgroup_get_from_path(const char *path)
|
|
|
if (kn) {
|
|
|
if (kernfs_type(kn) == KERNFS_DIR) {
|
|
|
cgrp = kn->priv;
|
|
|
- cgroup_get(cgrp);
|
|
|
+ cgroup_get_live(cgrp);
|
|
|
} else {
|
|
|
cgrp = ERR_PTR(-ENOTDIR);
|
|
|
}
|
|
@@ -5027,6 +5032,11 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd)
|
|
|
|
|
|
/* Socket clone path */
|
|
|
if (skcd->val) {
|
|
|
+ /*
|
|
|
+ * We might be cloning a socket which is left in an empty
|
|
|
+ * cgroup and the cgroup might have already been rmdir'd.
|
|
|
+ * Don't use cgroup_get_live().
|
|
|
+ */
|
|
|
cgroup_get(sock_cgroup_ptr(skcd));
|
|
|
return;
|
|
|
}
|