diff options
author | Li Zefan <lizefan@huawei.com> | 2013-01-24 01:31:42 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-01-24 15:05:18 -0500 |
commit | be44562613851235d801d41d5b3976dc4333f622 (patch) | |
tree | ed68df6a444cd106b04f96645c03a6f97fcc2e0c /kernel/cgroup.c | |
parent | 86a3db5643c7d29bb36ca85c7a4bb67ad4d88d77 (diff) |
cgroup: remove synchronize_rcu() from cgroup_diput()
Free cgroup via call_rcu(). The actual work is done through
workqueue.
Signed-off-by: Li Zefan <lizefan@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index af993919aa04..02e4f201472e 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -852,12 +852,52 @@ static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb) | |||
852 | return inode; | 852 | return inode; |
853 | } | 853 | } |
854 | 854 | ||
855 | static void cgroup_free_fn(struct work_struct *work) | ||
856 | { | ||
857 | struct cgroup *cgrp = container_of(work, struct cgroup, free_work); | ||
858 | struct cgroup_subsys *ss; | ||
859 | |||
860 | mutex_lock(&cgroup_mutex); | ||
861 | /* | ||
862 | * Release the subsystem state objects. | ||
863 | */ | ||
864 | for_each_subsys(cgrp->root, ss) | ||
865 | ss->css_free(cgrp); | ||
866 | |||
867 | cgrp->root->number_of_cgroups--; | ||
868 | mutex_unlock(&cgroup_mutex); | ||
869 | |||
870 | /* | ||
871 | * Drop the active superblock reference that we took when we | ||
872 | * created the cgroup | ||
873 | */ | ||
874 | deactivate_super(cgrp->root->sb); | ||
875 | |||
876 | /* | ||
877 | * if we're getting rid of the cgroup, refcount should ensure | ||
878 | * that there are no pidlists left. | ||
879 | */ | ||
880 | BUG_ON(!list_empty(&cgrp->pidlists)); | ||
881 | |||
882 | simple_xattrs_free(&cgrp->xattrs); | ||
883 | |||
884 | ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id); | ||
885 | kfree(cgrp); | ||
886 | } | ||
887 | |||
888 | static void cgroup_free_rcu(struct rcu_head *head) | ||
889 | { | ||
890 | struct cgroup *cgrp = container_of(head, struct cgroup, rcu_head); | ||
891 | |||
892 | schedule_work(&cgrp->free_work); | ||
893 | } | ||
894 | |||
855 | static void cgroup_diput(struct dentry *dentry, struct inode *inode) | 895 | static void cgroup_diput(struct dentry *dentry, struct inode *inode) |
856 | { | 896 | { |
857 | /* is dentry a directory ? if so, kfree() associated cgroup */ | 897 | /* is dentry a directory ? if so, kfree() associated cgroup */ |
858 | if (S_ISDIR(inode->i_mode)) { | 898 | if (S_ISDIR(inode->i_mode)) { |
859 | struct cgroup *cgrp = dentry->d_fsdata; | 899 | struct cgroup *cgrp = dentry->d_fsdata; |
860 | struct cgroup_subsys *ss; | 900 | |
861 | BUG_ON(!(cgroup_is_removed(cgrp))); | 901 | BUG_ON(!(cgroup_is_removed(cgrp))); |
862 | /* It's possible for external users to be holding css | 902 | /* It's possible for external users to be holding css |
863 | * reference counts on a cgroup; css_put() needs to | 903 | * reference counts on a cgroup; css_put() needs to |
@@ -865,34 +905,7 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
865 | * the reference count in order to know if it needs to | 905 | * the reference count in order to know if it needs to |
866 | * queue the cgroup to be handled by the release | 906 | * queue the cgroup to be handled by the release |
867 | * agent */ | 907 | * agent */ |
868 | synchronize_rcu(); | 908 | call_rcu(&cgrp->rcu_head, cgroup_free_rcu); |
869 | |||
870 | mutex_lock(&cgroup_mutex); | ||
871 | /* | ||
872 | * Release the subsystem state objects. | ||
873 | */ | ||
874 | for_each_subsys(cgrp->root, ss) | ||
875 | ss->css_free(cgrp); | ||
876 | |||
877 | cgrp->root->number_of_cgroups--; | ||
878 | mutex_unlock(&cgroup_mutex); | ||
879 | |||
880 | /* | ||
881 | * Drop the active superblock reference that we took when we | ||
882 | * created the cgroup | ||
883 | */ | ||
884 | deactivate_super(cgrp->root->sb); | ||
885 | |||
886 | /* | ||
887 | * if we're getting rid of the cgroup, refcount should ensure | ||
888 | * that there are no pidlists left. | ||
889 | */ | ||
890 | BUG_ON(!list_empty(&cgrp->pidlists)); | ||
891 | |||
892 | simple_xattrs_free(&cgrp->xattrs); | ||
893 | |||
894 | ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id); | ||
895 | kfree(cgrp); | ||
896 | } else { | 909 | } else { |
897 | struct cfent *cfe = __d_cfe(dentry); | 910 | struct cfent *cfe = __d_cfe(dentry); |
898 | struct cgroup *cgrp = dentry->d_parent->d_fsdata; | 911 | struct cgroup *cgrp = dentry->d_parent->d_fsdata; |
@@ -1391,6 +1404,7 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) | |||
1391 | INIT_LIST_HEAD(&cgrp->allcg_node); | 1404 | INIT_LIST_HEAD(&cgrp->allcg_node); |
1392 | INIT_LIST_HEAD(&cgrp->release_list); | 1405 | INIT_LIST_HEAD(&cgrp->release_list); |
1393 | INIT_LIST_HEAD(&cgrp->pidlists); | 1406 | INIT_LIST_HEAD(&cgrp->pidlists); |
1407 | INIT_WORK(&cgrp->free_work, cgroup_free_fn); | ||
1394 | mutex_init(&cgrp->pidlist_mutex); | 1408 | mutex_init(&cgrp->pidlist_mutex); |
1395 | INIT_LIST_HEAD(&cgrp->event_list); | 1409 | INIT_LIST_HEAD(&cgrp->event_list); |
1396 | spin_lock_init(&cgrp->event_list_lock); | 1410 | spin_lock_init(&cgrp->event_list_lock); |