]> www.infradead.org Git - users/willy/xarray.git/commitdiff
cgroup: Convert cgroup_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Sat, 27 Oct 2018 03:24:58 +0000 (23:24 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:13 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
include/linux/cgroup-defs.h
kernel/cgroup/cgroup.c

index 430e219e3abafdf9ac308888b4e86b67108ec621..341d062905bec6f31e453251bed29ee528fd23f5 100644 (file)
@@ -355,7 +355,7 @@ struct cgroup {
        unsigned long flags;            /* "unsigned long" so bitops work */
 
        /*
-        * idr allocated in-hierarchy ID.
+        * In-hierarchy ID.
         *
         * ID 0 is not used, the ID of the root cgroup is always 1, and a
         * new cgroup will be assigned with a smallest available ID.
@@ -521,7 +521,7 @@ struct cgroup_root {
        unsigned int flags;
 
        /* IDs for cgroups in this hierarchy */
-       struct idr cgroup_idr;
+       struct xarray cgroup_ids;
 
        /* The path to use for release notifications. */
        char release_agent_path[PATH_MAX];
index 753afbca549fdaeba9c133c192c1927d1d9c6f3c..bc9c8fd63d8d21f13ac848eeeac3397527d4ac05 100644 (file)
@@ -90,7 +90,7 @@ char trace_cgroup_path[TRACE_CGROUP_PATH_LEN];
 bool cgroup_debug __read_mostly;
 
 /*
- * Protects cgroup_idr and css_idr so that IDs can be released without
+ * Protects css_idr so that IDs can be released without
  * grabbing cgroup_mutex.
  */
 static DEFINE_SPINLOCK(cgroup_idr_lock);
@@ -1309,10 +1309,7 @@ static void cgroup_exit_root_id(struct cgroup_root *root)
 
 void cgroup_free_root(struct cgroup_root *root)
 {
-       if (root) {
-               idr_destroy(&root->cgroup_idr);
-               kfree(root);
-       }
+       kfree(root);
 }
 
 static void cgroup_destroy_root(struct cgroup_root *root)
@@ -1976,7 +1973,7 @@ void init_cgroup_root(struct cgroup_fs_context *ctx)
        atomic_set(&root->nr_cgrps, 1);
        cgrp->root = root;
        init_cgroup_housekeeping(cgrp);
-       idr_init(&root->cgroup_idr);
+       xa_init_flags(&root->cgroup_ids, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH);
 
        root->flags = ctx->flags;
        if (ctx->release_agent)
@@ -1997,10 +1994,10 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
 
        lockdep_assert_held(&cgroup_mutex);
 
-       ret = cgroup_idr_alloc(&root->cgroup_idr, root_cgrp, 1, 2, GFP_KERNEL);
+       ret = xa_insert_bh(&root->cgroup_ids, 1, root_cgrp, GFP_KERNEL);
        if (ret < 0)
                goto out;
-       root_cgrp->id = ret;
+       root_cgrp->id = 1;
        root_cgrp->ancestor_ids[0] = ret;
 
        ret = percpu_ref_init(&root_cgrp->self.refcnt, css_release,
@@ -5036,7 +5033,7 @@ static void css_release_work_fn(struct work_struct *work)
                        tcgrp->nr_dying_descendants--;
                spin_unlock_irq(&css_set_lock);
 
-               cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
+               xa_erase_bh(&cgrp->root->cgroup_ids, cgrp->id);
                cgrp->id = -1;
 
                /*
@@ -5226,12 +5223,10 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
                        goto out_cancel_ref;
        }
 
-       /*
-        * Temporarily set the pointer to NULL, so idr_find() won't return
-        * a half-baked cgroup.
-        */
-       cgrp->id = cgroup_idr_alloc(&root->cgroup_idr, NULL, 2, 0, GFP_KERNEL);
-       if (cgrp->id < 0) {
+       /* Use a NULL pointer, so we won't find a half-baked cgroup. */
+       ret = xa_alloc_bh(&root->cgroup_ids, &cgrp->id, NULL, xa_limit_32b,
+                       GFP_KERNEL);
+       if (ret < 0) {
                ret = -ENOMEM;
                goto out_stat_exit;
        }
@@ -5244,7 +5239,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
 
        ret = psi_cgroup_alloc(cgrp);
        if (ret)
-               goto out_idr_free;
+               goto out_xa_free;
 
        ret = cgroup_bpf_inherit(cgrp);
        if (ret)
@@ -5293,7 +5288,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
         * @cgrp is now fully operational.  If something fails after this
         * point, it'll be released via the normal destruction path.
         */
-       cgroup_idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
+       xa_store_bh(&root->cgroup_ids, cgrp->id, cgrp, 0);
 
        /*
         * On the default hierarchy, a child doesn't automatically inherit
@@ -5308,8 +5303,8 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
 
 out_psi_free:
        psi_cgroup_free(cgrp);
-out_idr_free:
-       cgroup_idr_remove(&root->cgroup_idr, cgrp->id);
+out_xa_free:
+       xa_erase_bh(&root->cgroup_ids, cgrp->id);
 out_stat_exit:
        if (cgroup_on_dfl(parent))
                cgroup_rstat_exit(cgrp);