From: Matthew Wilcox Date: Sat, 3 Nov 2018 12:23:42 +0000 (-0400) Subject: cgroup: Convert css_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6282b7e48084d09a3ceace18b072bb8e929fc87d;p=users%2Fwilly%2Fxarray.git cgroup: Convert css_idr to XArray Remove the internal wrappers as the XArray behaves exactly how the cgroup code wishes the IDR did. Signed-off-by: Matthew Wilcox --- diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 341d062905be..c17fa7b658da 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include @@ -700,8 +700,8 @@ struct cgroup_subsys { /* link to parent, protected by cgroup_lock() */ struct cgroup_root *root; - /* idr for css->id */ - struct idr css_idr; + /* xarray for css->id */ + struct xarray css_xa; /* * List of cftypes. Each entry is the first entry of an array diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index bc9c8fd63d8d..11b52b76ff6a 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -89,12 +89,6 @@ DEFINE_SPINLOCK(trace_cgroup_path_lock); char trace_cgroup_path[TRACE_CGROUP_PATH_LEN]; bool cgroup_debug __read_mostly; -/* - * Protects css_idr so that IDs can be released without - * grabbing cgroup_mutex. - */ -static DEFINE_SPINLOCK(cgroup_idr_lock); - /* * Protects cgroup_file->kn for !self csses. It synchronizes notifications * against file removal/re-creation across css hiding. @@ -300,37 +294,6 @@ bool cgroup_on_dfl(const struct cgroup *cgrp) return cgrp->root == &cgrp_dfl_root; } -/* IDR wrappers which synchronize using cgroup_idr_lock */ -static int cgroup_idr_alloc(struct idr *idr, void *ptr, int start, int end, - gfp_t gfp_mask) -{ - int ret; - - idr_preload(gfp_mask); - spin_lock_bh(&cgroup_idr_lock); - ret = idr_alloc(idr, ptr, start, end, gfp_mask & ~__GFP_DIRECT_RECLAIM); - spin_unlock_bh(&cgroup_idr_lock); - idr_preload_end(); - return ret; -} - -static void *cgroup_idr_replace(struct idr *idr, void *ptr, int id) -{ - void *ret; - - spin_lock_bh(&cgroup_idr_lock); - ret = idr_replace(idr, ptr, id); - spin_unlock_bh(&cgroup_idr_lock); - return ret; -} - -static void cgroup_idr_remove(struct idr *idr, int id) -{ - spin_lock_bh(&cgroup_idr_lock); - idr_remove(idr, id); - spin_unlock_bh(&cgroup_idr_lock); -} - static bool cgroup_has_tasks(struct cgroup *cgrp) { return cgrp->nr_populated_csets; @@ -4961,7 +4924,7 @@ static void css_free_rwork_fn(struct work_struct *work) int id = css->id; ss->css_free(css); - cgroup_idr_remove(&ss->css_idr, id); + xa_erase_bh(&ss->css_xa, id); cgroup_put(cgrp); if (parent) @@ -5015,7 +4978,7 @@ static void css_release_work_fn(struct work_struct *work) list_del_rcu(&css->rstat_css_node); } - cgroup_idr_replace(&ss->css_idr, NULL, css->id); + xa_store_bh(&ss->css_xa, css->id, NULL, 0); if (ss->css_released) ss->css_released(css); } else { @@ -5162,14 +5125,15 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp, if (err) goto err_free_css; - err = cgroup_idr_alloc(&ss->css_idr, NULL, 2, 0, GFP_KERNEL); + err = xa_alloc_bh(&ss->css_xa, &css->id, NULL, xa_limit_31b, + GFP_KERNEL); if (err < 0) goto err_free_css; - css->id = err; + BUG_ON(css->id < 2); /* @css is ready to be brought online now, make it visible */ list_add_tail_rcu(&css->sibling, &parent_css->children); - cgroup_idr_replace(&ss->css_idr, css, css->id); + xa_store_bh(&ss->css_xa, css->id, css, 0); err = online_css(css); if (err) @@ -5609,7 +5573,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early) mutex_lock(&cgroup_mutex); - idr_init(&ss->css_idr); + xa_init_flags(&ss->css_xa, XA_FLAGS_ALLOC1 | XA_FLAGS_LOCK_BH); INIT_LIST_HEAD(&ss->cfts); /* Create the root cgroup state for this subsystem */ @@ -5624,13 +5588,12 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early) * percpu_ref during early init. Disable refcnting. */ css->flags |= CSS_NO_REF; + css->id = 1; - if (early) { + if (!early) { /* allocation can't be done safely during early init */ - css->id = 1; - } else { - css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL); - BUG_ON(css->id < 0); + void *old = xa_store_bh(&ss->css_xa, 1, css, GFP_KERNEL); + BUG_ON(old); } /* Update the init_css_set to contain a subsys @@ -5736,9 +5699,8 @@ int __init cgroup_init(void) struct cgroup_subsys_state *css = init_css_set.subsys[ss->id]; - css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, - GFP_KERNEL); - BUG_ON(css->id < 0); + void *p = xa_store_bh(&ss->css_xa, 1, css, GFP_KERNEL); + BUG_ON(p != NULL); } else { cgroup_init_subsys(ss, false); } @@ -6211,7 +6173,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry, struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss) { WARN_ON_ONCE(!rcu_read_lock_held()); - return idr_find(&ss->css_idr, id); + return xa_load(&ss->css_xa, id); } /**