aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h37
-rw-r--r--kernel/cgroup.c248
2 files changed, 1 insertions, 284 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 3561d305b1e0..39c1d9469677 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -612,11 +612,6 @@ struct cgroup_subsys {
612 int subsys_id; 612 int subsys_id;
613 int disabled; 613 int disabled;
614 int early_init; 614 int early_init;
615 /*
616 * True if this subsys uses ID. ID is not available before cgroup_init()
617 * (not available in early_init time.)
618 */
619 bool use_id;
620 615
621 /* 616 /*
622 * If %false, this subsystem is properly hierarchical - 617 * If %false, this subsystem is properly hierarchical -
@@ -642,9 +637,6 @@ struct cgroup_subsys {
642 */ 637 */
643 struct cgroupfs_root *root; 638 struct cgroupfs_root *root;
644 struct list_head sibling; 639 struct list_head sibling;
645 /* used when use_id == true */
646 struct idr idr;
647 spinlock_t id_lock;
648 640
649 /* list of cftype_sets */ 641 /* list of cftype_sets */
650 struct list_head cftsets; 642 struct list_head cftsets;
@@ -875,35 +867,6 @@ int css_scan_tasks(struct cgroup_subsys_state *css,
875int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); 867int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
876int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from); 868int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
877 869
878/*
879 * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
880 * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
881 * CSS ID is assigned at cgroup allocation (create) automatically
882 * and removed when subsys calls free_css_id() function. This is because
883 * the lifetime of cgroup_subsys_state is subsys's matter.
884 *
885 * Looking up and scanning function should be called under rcu_read_lock().
886 * Taking cgroup_mutex is not necessary for following calls.
887 * But the css returned by this routine can be "not populated yet" or "being
888 * destroyed". The caller should check css and cgroup's status.
889 */
890
891/*
892 * Typically Called at ->destroy(), or somewhere the subsys frees
893 * cgroup_subsys_state.
894 */
895void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css);
896
897/* Find a cgroup_subsys_state which has given ID */
898
899struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id);
900
901/* Returns true if root is ancestor of cg */
902bool css_is_ancestor(struct cgroup_subsys_state *cg,
903 const struct cgroup_subsys_state *root);
904
905/* Get id and depth of css */
906unsigned short css_id(struct cgroup_subsys_state *css);
907struct cgroup_subsys_state *css_from_dir(struct dentry *dentry, 870struct cgroup_subsys_state *css_from_dir(struct dentry *dentry,
908 struct cgroup_subsys *ss); 871 struct cgroup_subsys *ss);
909 872
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 2418b6e71a85..a5629f1df13a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -125,38 +125,6 @@ struct cfent {
125}; 125};
126 126
127/* 127/*
128 * CSS ID -- ID per subsys's Cgroup Subsys State(CSS). used only when
129 * cgroup_subsys->use_id != 0.
130 */
131#define CSS_ID_MAX (65535)
132struct css_id {
133 /*
134 * The css to which this ID points. This pointer is set to valid value
135 * after cgroup is populated. If cgroup is removed, this will be NULL.
136 * This pointer is expected to be RCU-safe because destroy()
137 * is called after synchronize_rcu(). But for safe use, css_tryget()
138 * should be used for avoiding race.
139 */
140 struct cgroup_subsys_state __rcu *css;
141 /*
142 * ID of this css.
143 */
144 unsigned short id;
145 /*
146 * Depth in hierarchy which this ID belongs to.
147 */
148 unsigned short depth;
149 /*
150 * ID is freed by RCU. (and lookup routine is RCU safe.)
151 */
152 struct rcu_head rcu_head;
153 /*
154 * Hierarchy of CSS ID belongs to.
155 */
156 unsigned short stack[0]; /* Array of Length (depth+1) */
157};
158
159/*
160 * cgroup_event represents events which userspace want to receive. 128 * cgroup_event represents events which userspace want to receive.
161 */ 129 */
162struct cgroup_event { 130struct cgroup_event {
@@ -387,9 +355,6 @@ struct cgrp_cset_link {
387static struct css_set init_css_set; 355static struct css_set init_css_set;
388static struct cgrp_cset_link init_cgrp_cset_link; 356static struct cgrp_cset_link init_cgrp_cset_link;
389 357
390static int cgroup_init_idr(struct cgroup_subsys *ss,
391 struct cgroup_subsys_state *css);
392
393/* 358/*
394 * css_set_lock protects the list of css_set objects, and the chain of 359 * css_set_lock protects the list of css_set objects, and the chain of
395 * tasks off each css_set. Nests outside task->alloc_lock due to 360 * tasks off each css_set. Nests outside task->alloc_lock due to
@@ -841,8 +806,6 @@ static struct backing_dev_info cgroup_backing_dev_info = {
841 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, 806 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
842}; 807};
843 808
844static int alloc_css_id(struct cgroup_subsys_state *child_css);
845
846static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb) 809static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb)
847{ 810{
848 struct inode *inode = new_inode(sb); 811 struct inode *inode = new_inode(sb);
@@ -4242,21 +4205,6 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
4242 goto err; 4205 goto err;
4243 } 4206 }
4244 } 4207 }
4245
4246 /* This cgroup is ready now */
4247 for_each_root_subsys(cgrp->root, ss) {
4248 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss);
4249 struct css_id *id = rcu_dereference_protected(css->id, true);
4250
4251 /*
4252 * Update id->css pointer and make this css visible from
4253 * CSS ID functions. This pointer will be dereferened
4254 * from RCU-read-side without locks.
4255 */
4256 if (id)
4257 rcu_assign_pointer(id->css, css);
4258 }
4259
4260 return 0; 4208 return 0;
4261err: 4209err:
4262 cgroup_clear_dir(cgrp, subsys_mask); 4210 cgroup_clear_dir(cgrp, subsys_mask);
@@ -4325,7 +4273,6 @@ static void init_css(struct cgroup_subsys_state *css, struct cgroup_subsys *ss,
4325 css->cgroup = cgrp; 4273 css->cgroup = cgrp;
4326 css->ss = ss; 4274 css->ss = ss;
4327 css->flags = 0; 4275 css->flags = 0;
4328 css->id = NULL;
4329 4276
4330 if (cgrp->parent) 4277 if (cgrp->parent)
4331 css->parent = cgroup_css(cgrp->parent, ss); 4278 css->parent = cgroup_css(cgrp->parent, ss);
@@ -4457,12 +4404,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4457 goto err_free_all; 4404 goto err_free_all;
4458 4405
4459 init_css(css, ss, cgrp); 4406 init_css(css, ss, cgrp);
4460
4461 if (ss->use_id) {
4462 err = alloc_css_id(css);
4463 if (err)
4464 goto err_free_all;
4465 }
4466 } 4407 }
4467 4408
4468 /* 4409 /*
@@ -4927,12 +4868,6 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
4927 4868
4928 /* our new subsystem will be attached to the dummy hierarchy. */ 4869 /* our new subsystem will be attached to the dummy hierarchy. */
4929 init_css(css, ss, cgroup_dummy_top); 4870 init_css(css, ss, cgroup_dummy_top);
4930 /* init_idr must be after init_css() because it sets css->id. */
4931 if (ss->use_id) {
4932 ret = cgroup_init_idr(ss, css);
4933 if (ret)
4934 goto err_unload;
4935 }
4936 4871
4937 /* 4872 /*
4938 * Now we need to entangle the css into the existing css_sets. unlike 4873 * Now we need to entangle the css into the existing css_sets. unlike
@@ -4998,9 +4933,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
4998 4933
4999 offline_css(cgroup_css(cgroup_dummy_top, ss)); 4934 offline_css(cgroup_css(cgroup_dummy_top, ss));
5000 4935
5001 if (ss->use_id)
5002 idr_destroy(&ss->idr);
5003
5004 /* deassign the subsys_id */ 4936 /* deassign the subsys_id */
5005 cgroup_subsys[ss->subsys_id] = NULL; 4937 cgroup_subsys[ss->subsys_id] = NULL;
5006 4938
@@ -5027,8 +4959,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
5027 /* 4959 /*
5028 * remove subsystem's css from the cgroup_dummy_top and free it - 4960 * remove subsystem's css from the cgroup_dummy_top and free it -
5029 * need to free before marking as null because ss->css_free needs 4961 * need to free before marking as null because ss->css_free needs
5030 * the cgrp->subsys pointer to find their state. note that this 4962 * the cgrp->subsys pointer to find their state.
5031 * also takes care of freeing the css_id.
5032 */ 4963 */
5033 ss->css_free(cgroup_css(cgroup_dummy_top, ss)); 4964 ss->css_free(cgroup_css(cgroup_dummy_top, ss));
5034 RCU_INIT_POINTER(cgroup_dummy_top->subsys[ss->subsys_id], NULL); 4965 RCU_INIT_POINTER(cgroup_dummy_top->subsys[ss->subsys_id], NULL);
@@ -5099,8 +5030,6 @@ int __init cgroup_init(void)
5099 for_each_builtin_subsys(ss, i) { 5030 for_each_builtin_subsys(ss, i) {
5100 if (!ss->early_init) 5031 if (!ss->early_init)
5101 cgroup_init_subsys(ss); 5032 cgroup_init_subsys(ss);
5102 if (ss->use_id)
5103 cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]);
5104 } 5033 }
5105 5034
5106 /* allocate id for the dummy hierarchy */ 5035 /* allocate id for the dummy hierarchy */
@@ -5520,181 +5449,6 @@ static int __init cgroup_disable(char *str)
5520} 5449}
5521__setup("cgroup_disable=", cgroup_disable); 5450__setup("cgroup_disable=", cgroup_disable);
5522 5451
5523/*
5524 * Functons for CSS ID.
5525 */
5526
5527/* to get ID other than 0, this should be called when !cgroup_is_dead() */
5528unsigned short css_id(struct cgroup_subsys_state *css)
5529{
5530 struct css_id *cssid;
5531
5532 /*
5533 * This css_id() can return correct value when somone has refcnt
5534 * on this or this is under rcu_read_lock(). Once css->id is allocated,
5535 * it's unchanged until freed.
5536 */
5537 cssid = rcu_dereference_raw(css->id);
5538
5539 if (cssid)
5540 return cssid->id;
5541 return 0;
5542}
5543EXPORT_SYMBOL_GPL(css_id);
5544
5545/**
5546 * css_is_ancestor - test "root" css is an ancestor of "child"
5547 * @child: the css to be tested.
5548 * @root: the css supporsed to be an ancestor of the child.
5549 *
5550 * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
5551 * this function reads css->id, the caller must hold rcu_read_lock().
5552 * But, considering usual usage, the csses should be valid objects after test.
5553 * Assuming that the caller will do some action to the child if this returns
5554 * returns true, the caller must take "child";s reference count.
5555 * If "child" is valid object and this returns true, "root" is valid, too.
5556 */
5557
5558bool css_is_ancestor(struct cgroup_subsys_state *child,
5559 const struct cgroup_subsys_state *root)
5560{
5561 struct css_id *child_id;
5562 struct css_id *root_id;
5563
5564 child_id = rcu_dereference(child->id);
5565 if (!child_id)
5566 return false;
5567 root_id = rcu_dereference(root->id);
5568 if (!root_id)
5569 return false;
5570 if (child_id->depth < root_id->depth)
5571 return false;
5572 if (child_id->stack[root_id->depth] != root_id->id)
5573 return false;
5574 return true;
5575}
5576
5577void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
5578{
5579 struct css_id *id = rcu_dereference_protected(css->id, true);
5580
5581 /* When this is called before css_id initialization, id can be NULL */
5582 if (!id)
5583 return;
5584
5585 BUG_ON(!ss->use_id);
5586
5587 rcu_assign_pointer(id->css, NULL);
5588 rcu_assign_pointer(css->id, NULL);
5589 spin_lock(&ss->id_lock);
5590 idr_remove(&ss->idr, id->id);
5591 spin_unlock(&ss->id_lock);
5592 kfree_rcu(id, rcu_head);
5593}
5594EXPORT_SYMBOL_GPL(free_css_id);
5595
5596/*
5597 * This is called by init or create(). Then, calls to this function are
5598 * always serialized (By cgroup_mutex() at create()).
5599 */
5600
5601static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
5602{
5603 struct css_id *newid;
5604 int ret, size;
5605
5606 BUG_ON(!ss->use_id);
5607
5608 size = sizeof(*newid) + sizeof(unsigned short) * (depth + 1);
5609 newid = kzalloc(size, GFP_KERNEL);
5610 if (!newid)
5611 return ERR_PTR(-ENOMEM);
5612
5613 idr_preload(GFP_KERNEL);
5614 spin_lock(&ss->id_lock);
5615 /* Don't use 0. allocates an ID of 1-65535 */
5616 ret = idr_alloc(&ss->idr, newid, 1, CSS_ID_MAX + 1, GFP_NOWAIT);
5617 spin_unlock(&ss->id_lock);
5618 idr_preload_end();
5619
5620 /* Returns error when there are no free spaces for new ID.*/
5621 if (ret < 0)
5622 goto err_out;
5623
5624 newid->id = ret;
5625 newid->depth = depth;
5626 return newid;
5627err_out:
5628 kfree(newid);
5629 return ERR_PTR(ret);
5630
5631}
5632
5633static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
5634 struct cgroup_subsys_state *rootcss)
5635{
5636 struct css_id *newid;
5637
5638 spin_lock_init(&ss->id_lock);
5639 idr_init(&ss->idr);
5640
5641 newid = get_new_cssid(ss, 0);
5642 if (IS_ERR(newid))
5643 return PTR_ERR(newid);
5644
5645 newid->stack[0] = newid->id;
5646 RCU_INIT_POINTER(newid->css, rootcss);
5647 RCU_INIT_POINTER(rootcss->id, newid);
5648 return 0;
5649}
5650
5651static int alloc_css_id(struct cgroup_subsys_state *child_css)
5652{
5653 struct cgroup_subsys_state *parent_css = css_parent(child_css);
5654 struct css_id *child_id, *parent_id;
5655 int i, depth;
5656
5657 parent_id = rcu_dereference_protected(parent_css->id, true);
5658 depth = parent_id->depth + 1;
5659
5660 child_id = get_new_cssid(child_css->ss, depth);
5661 if (IS_ERR(child_id))
5662 return PTR_ERR(child_id);
5663
5664 for (i = 0; i < depth; i++)
5665 child_id->stack[i] = parent_id->stack[i];
5666 child_id->stack[depth] = child_id->id;
5667 /*
5668 * child_id->css pointer will be set after this cgroup is available
5669 * see cgroup_populate_dir()
5670 */
5671 rcu_assign_pointer(child_css->id, child_id);
5672
5673 return 0;
5674}
5675
5676/**
5677 * css_lookup - lookup css by id
5678 * @ss: cgroup subsys to be looked into.
5679 * @id: the id
5680 *
5681 * Returns pointer to cgroup_subsys_state if there is valid one with id.
5682 * NULL if not. Should be called under rcu_read_lock()
5683 */
5684struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id)
5685{
5686 struct css_id *cssid = NULL;
5687
5688 BUG_ON(!ss->use_id);
5689 cssid = idr_find(&ss->idr, id);
5690
5691 if (unlikely(!cssid))
5692 return NULL;
5693
5694 return rcu_dereference(cssid->css);
5695}
5696EXPORT_SYMBOL_GPL(css_lookup);
5697
5698/** 5452/**
5699 * css_from_dir - get corresponding css from the dentry of a cgroup dir 5453 * css_from_dir - get corresponding css from the dentry of a cgroup dir
5700 * @dentry: directory dentry of interest 5454 * @dentry: directory dentry of interest