aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e0839bcd48c8..8b729c278b64 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -90,6 +90,14 @@ static DEFINE_MUTEX(cgroup_mutex);
90static DEFINE_MUTEX(cgroup_root_mutex); 90static DEFINE_MUTEX(cgroup_root_mutex);
91 91
92/* 92/*
93 * cgroup destruction makes heavy use of work items and there can be a lot
94 * of concurrent destructions. Use a separate workqueue so that cgroup
95 * destruction work items don't end up filling up max_active of system_wq
96 * which may lead to deadlock.
97 */
98static struct workqueue_struct *cgroup_destroy_wq;
99
100/*
93 * Generate an array of cgroup subsystem pointers. At boot time, this is 101 * Generate an array of cgroup subsystem pointers. At boot time, this is
94 * populated with the built in subsystems, and modular subsystems are 102 * populated with the built in subsystems, and modular subsystems are
95 * registered after that. The mutable section of this array is protected by 103 * registered after that. The mutable section of this array is protected by
@@ -191,6 +199,7 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp);
191static int cgroup_destroy_locked(struct cgroup *cgrp); 199static int cgroup_destroy_locked(struct cgroup *cgrp);
192static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[], 200static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
193 bool is_add); 201 bool is_add);
202static int cgroup_file_release(struct inode *inode, struct file *file);
194 203
195/** 204/**
196 * cgroup_css - obtain a cgroup's css for the specified subsystem 205 * cgroup_css - obtain a cgroup's css for the specified subsystem
@@ -871,7 +880,7 @@ static void cgroup_free_rcu(struct rcu_head *head)
871 struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head); 880 struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head);
872 881
873 INIT_WORK(&cgrp->destroy_work, cgroup_free_fn); 882 INIT_WORK(&cgrp->destroy_work, cgroup_free_fn);
874 schedule_work(&cgrp->destroy_work); 883 queue_work(cgroup_destroy_wq, &cgrp->destroy_work);
875} 884}
876 885
877static void cgroup_diput(struct dentry *dentry, struct inode *inode) 886static void cgroup_diput(struct dentry *dentry, struct inode *inode)
@@ -895,11 +904,6 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)
895 iput(inode); 904 iput(inode);
896} 905}
897 906
898static int cgroup_delete(const struct dentry *d)
899{
900 return 1;
901}
902
903static void remove_dir(struct dentry *d) 907static void remove_dir(struct dentry *d)
904{ 908{
905 struct dentry *parent = dget(d->d_parent); 909 struct dentry *parent = dget(d->d_parent);
@@ -1486,7 +1490,7 @@ static int cgroup_get_rootdir(struct super_block *sb)
1486{ 1490{
1487 static const struct dentry_operations cgroup_dops = { 1491 static const struct dentry_operations cgroup_dops = {
1488 .d_iput = cgroup_diput, 1492 .d_iput = cgroup_diput,
1489 .d_delete = cgroup_delete, 1493 .d_delete = always_delete_dentry,
1490 }; 1494 };
1491 1495
1492 struct inode *inode = 1496 struct inode *inode =
@@ -2426,7 +2430,7 @@ static const struct file_operations cgroup_seqfile_operations = {
2426 .read = seq_read, 2430 .read = seq_read,
2427 .write = cgroup_file_write, 2431 .write = cgroup_file_write,
2428 .llseek = seq_lseek, 2432 .llseek = seq_lseek,
2429 .release = single_release, 2433 .release = cgroup_file_release,
2430}; 2434};
2431 2435
2432static int cgroup_file_open(struct inode *inode, struct file *file) 2436static int cgroup_file_open(struct inode *inode, struct file *file)
@@ -2487,6 +2491,8 @@ static int cgroup_file_release(struct inode *inode, struct file *file)
2487 ret = cft->release(inode, file); 2491 ret = cft->release(inode, file);
2488 if (css->ss) 2492 if (css->ss)
2489 css_put(css); 2493 css_put(css);
2494 if (file->f_op == &cgroup_seqfile_operations)
2495 single_release(inode, file);
2490 return ret; 2496 return ret;
2491} 2497}
2492 2498
@@ -4254,7 +4260,7 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head)
4254 * css_put(). dput() requires process context which we don't have. 4260 * css_put(). dput() requires process context which we don't have.
4255 */ 4261 */
4256 INIT_WORK(&css->destroy_work, css_free_work_fn); 4262 INIT_WORK(&css->destroy_work, css_free_work_fn);
4257 schedule_work(&css->destroy_work); 4263 queue_work(cgroup_destroy_wq, &css->destroy_work);
4258} 4264}
4259 4265
4260static void css_release(struct percpu_ref *ref) 4266static void css_release(struct percpu_ref *ref)
@@ -4544,7 +4550,7 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
4544 container_of(ref, struct cgroup_subsys_state, refcnt); 4550 container_of(ref, struct cgroup_subsys_state, refcnt);
4545 4551
4546 INIT_WORK(&css->destroy_work, css_killed_work_fn); 4552 INIT_WORK(&css->destroy_work, css_killed_work_fn);
4547 schedule_work(&css->destroy_work); 4553 queue_work(cgroup_destroy_wq, &css->destroy_work);
4548} 4554}
4549 4555
4550/** 4556/**
@@ -5068,6 +5074,22 @@ out:
5068 return err; 5074 return err;
5069} 5075}
5070 5076
5077static int __init cgroup_wq_init(void)
5078{
5079 /*
5080 * There isn't much point in executing destruction path in
5081 * parallel. Good chunk is serialized with cgroup_mutex anyway.
5082 * Use 1 for @max_active.
5083 *
5084 * We would prefer to do this in cgroup_init() above, but that
5085 * is called before init_workqueues(): so leave this until after.
5086 */
5087 cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1);
5088 BUG_ON(!cgroup_destroy_wq);
5089 return 0;
5090}
5091core_initcall(cgroup_wq_init);
5092
5071/* 5093/*
5072 * proc_cgroup_show() 5094 * proc_cgroup_show()
5073 * - Print task's cgroup paths into seq_file, one line for each hierarchy 5095 * - Print task's cgroup paths into seq_file, one line for each hierarchy