Merge branch 'for-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[platform/kernel/linux-starfive.git] / kernel / cgroup / cgroup.c
index 69e65d2..0b1ffe1 100644 (file)
@@ -1928,6 +1928,9 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask, int ref_flags)
        if (ret)
                goto destroy_root;
 
+       ret = cgroup_bpf_inherit(root_cgrp);
+       WARN_ON_ONCE(ret);
+
        trace_cgroup_setup_root(root);
 
        /*
@@ -2343,6 +2346,14 @@ out_release_tset:
                list_del_init(&cset->mg_node);
        }
        spin_unlock_irq(&css_set_lock);
+
+       /*
+        * Re-initialize the cgroup_taskset structure in case it is reused
+        * again in another cgroup_migrate_add_task()/cgroup_migrate_execute()
+        * iteration.
+        */
+       tset->nr_tasks = 0;
+       tset->csets    = &tset->src_csets;
        return ret;
 }
 
@@ -4792,6 +4803,9 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
        cgrp->self.parent = &parent->self;
        cgrp->root = root;
        cgrp->level = level;
+       ret = cgroup_bpf_inherit(cgrp);
+       if (ret)
+               goto out_idr_free;
 
        for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
                cgrp->ancestor_ids[tcgrp->level] = tcgrp->id;
@@ -4826,13 +4840,12 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
        if (!cgroup_on_dfl(cgrp))
                cgrp->subtree_control = cgroup_control(cgrp);
 
-       if (parent)
-               cgroup_bpf_inherit(cgrp, parent);
-
        cgroup_propagate_control(cgrp);
 
        return cgrp;
 
+out_idr_free:
+       cgroup_idr_remove(&root->cgroup_idr, cgrp->id);
 out_stat_exit:
        if (cgroup_on_dfl(parent))
                cgroup_stat_exit(cgrp);
@@ -5820,14 +5833,33 @@ void cgroup_sk_free(struct sock_cgroup_data *skcd)
 #endif /* CONFIG_SOCK_CGROUP_DATA */
 
 #ifdef CONFIG_CGROUP_BPF
-int cgroup_bpf_update(struct cgroup *cgrp, struct bpf_prog *prog,
-                     enum bpf_attach_type type, bool overridable)
+int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
+                     enum bpf_attach_type type, u32 flags)
+{
+       int ret;
+
+       mutex_lock(&cgroup_mutex);
+       ret = __cgroup_bpf_attach(cgrp, prog, type, flags);
+       mutex_unlock(&cgroup_mutex);
+       return ret;
+}
+int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
+                     enum bpf_attach_type type, u32 flags)
+{
+       int ret;
+
+       mutex_lock(&cgroup_mutex);
+       ret = __cgroup_bpf_detach(cgrp, prog, type, flags);
+       mutex_unlock(&cgroup_mutex);
+       return ret;
+}
+int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+                    union bpf_attr __user *uattr)
 {
-       struct cgroup *parent = cgroup_parent(cgrp);
        int ret;
 
        mutex_lock(&cgroup_mutex);
-       ret = __cgroup_bpf_update(cgrp, parent, prog, type, overridable);
+       ret = __cgroup_bpf_query(cgrp, attr, uattr);
        mutex_unlock(&cgroup_mutex);
        return ret;
 }