]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cgroup: Minor reorganization of cgroup_create()
authorTejun Heo <tj@kernel.org>
Wed, 14 May 2025 04:43:41 +0000 (00:43 -0400)
committerTejun Heo <tj@kernel.org>
Thu, 22 May 2025 19:19:57 +0000 (09:19 -1000)
cgroup_bpf init and exit handling will be moved to a notifier chain. In
prepartion, reorganize cgroup_create() a bit so that the new cgroup is fully
initialized before any outside changes are made.

- cgrp->ancestors[] initialization and the hierarchical nr_descendants and
  nr_frozen_descendants updates were in the same loop. Separate them out and
  do the former earlier and do the latter later.

- Relocate cgroup_bpf_inherit() call so that it's after all cgroup
  initializations are complete.

No visible behavior changes expected.

Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/cgroup/cgroup.c

index 44baa03187137bf05f617155163267c819caafb3..98a0c32ef98b592d6fdf7417a0679dae1acbd919 100644 (file)
@@ -5660,7 +5660,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
        struct cgroup_root *root = parent->root;
        struct cgroup *cgrp, *tcgrp;
        struct kernfs_node *kn;
-       int level = parent->level + 1;
+       int i, level = parent->level + 1;
        int ret;
 
        /* allocate the cgroup and its ID, 0 is reserved for the root */
@@ -5700,11 +5700,8 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
        if (ret)
                goto out_stat_exit;
 
-       if (cgrp->root == &cgrp_dfl_root) {
-               ret = cgroup_bpf_inherit(cgrp);
-               if (ret)
-                       goto out_psi_free;
-       }
+       for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp))
+               cgrp->ancestors[tcgrp->level] = tcgrp;
 
        /*
         * New cgroup inherits effective freeze counter, and
@@ -5722,24 +5719,6 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
                set_bit(CGRP_FROZEN, &cgrp->flags);
        }
 
-       spin_lock_irq(&css_set_lock);
-       for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
-               cgrp->ancestors[tcgrp->level] = tcgrp;
-
-               if (tcgrp != cgrp) {
-                       tcgrp->nr_descendants++;
-
-                       /*
-                        * If the new cgroup is frozen, all ancestor cgroups
-                        * get a new frozen descendant, but their state can't
-                        * change because of this.
-                        */
-                       if (cgrp->freezer.e_freeze)
-                               tcgrp->freezer.nr_frozen_descendants++;
-               }
-       }
-       spin_unlock_irq(&css_set_lock);
-
        if (notify_on_release(parent))
                set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
 
@@ -5748,7 +5727,28 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
 
        cgrp->self.serial_nr = css_serial_nr_next++;
 
+       if (cgrp->root == &cgrp_dfl_root) {
+               ret = cgroup_bpf_inherit(cgrp);
+               if (ret)
+                       goto out_psi_free;
+       }
+
        /* allocation complete, commit to creation */
+       spin_lock_irq(&css_set_lock);
+       for (i = 0; i < level; i++) {
+               tcgrp = cgrp->ancestors[i];
+               tcgrp->nr_descendants++;
+
+               /*
+                * If the new cgroup is frozen, all ancestor cgroups get a new
+                * frozen descendant, but their state can't change because of
+                * this.
+                */
+               if (cgrp->freezer.e_freeze)
+                       tcgrp->freezer.nr_frozen_descendants++;
+       }
+       spin_unlock_irq(&css_set_lock);
+
        list_add_tail_rcu(&cgrp->self.sibling, &cgroup_parent(cgrp)->self.children);
        atomic_inc(&root->nr_cgrps);
        cgroup_get_live(parent);