aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-08-08 20:11:23 -0400
committerTejun Heo <tj@kernel.org>2013-08-08 20:11:23 -0400
commit2bb566cb68dfafad328af666ebadf0e49accd6ca (patch)
tree700bd0b0f325e9eebf4b0c91ae31d1872f471e39 /kernel/cgroup.c
parenteb95419b023abacb415e2a18fea899023ce7624d (diff)
cgroup: add subsys backlink pointer to cftype
cgroup is transitioning to using css (cgroup_subsys_state) instead of cgroup as the primary subsystem handle. The cgroupfs file interface will be converted to use css's which requires finding out the subsystem from cftype so that the matching css can be determined from the cgroup. This patch adds cftype->ss which points to the subsystem the file belongs to. The field is initialized while a cftype is being registered. This makes it unnecessary to explicitly specify the subsystem for other cftype handling functions. @ss argument dropped from various cftype handling functions. This patch shouldn't introduce any behavior differences. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com> Acked-by: Vivek Goyal <vgoyal@redhat.com> Cc: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 271d9a5cde5f..c4bc8dac3b1d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -219,8 +219,8 @@ static struct cftype cgroup_base_files[];
219 219
220static void cgroup_offline_fn(struct work_struct *work); 220static void cgroup_offline_fn(struct work_struct *work);
221static int cgroup_destroy_locked(struct cgroup *cgrp); 221static int cgroup_destroy_locked(struct cgroup *cgrp);
222static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, 222static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
223 struct cftype cfts[], bool is_add); 223 bool is_add);
224 224
225/* convenient tests for these bits */ 225/* convenient tests for these bits */
226static inline bool cgroup_is_dead(const struct cgroup *cgrp) 226static inline bool cgroup_is_dead(const struct cgroup *cgrp)
@@ -974,7 +974,7 @@ static void cgroup_clear_dir(struct cgroup *cgrp, unsigned long subsys_mask)
974 if (!test_bit(i, &subsys_mask)) 974 if (!test_bit(i, &subsys_mask))
975 continue; 975 continue;
976 list_for_each_entry(set, &ss->cftsets, node) 976 list_for_each_entry(set, &ss->cftsets, node)
977 cgroup_addrm_files(cgrp, NULL, set->cfts, false); 977 cgroup_addrm_files(cgrp, set->cfts, false);
978 } 978 }
979} 979}
980 980
@@ -1623,7 +1623,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1623 */ 1623 */
1624 cred = override_creds(&init_cred); 1624 cred = override_creds(&init_cred);
1625 1625
1626 ret = cgroup_addrm_files(root_cgrp, NULL, cgroup_base_files, true); 1626 ret = cgroup_addrm_files(root_cgrp, cgroup_base_files, true);
1627 if (ret) 1627 if (ret)
1628 goto rm_base_files; 1628 goto rm_base_files;
1629 1629
@@ -1681,7 +1681,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
1681 1681
1682 rm_base_files: 1682 rm_base_files:
1683 free_cgrp_cset_links(&tmp_links); 1683 free_cgrp_cset_links(&tmp_links);
1684 cgroup_addrm_files(&root->top_cgroup, NULL, cgroup_base_files, false); 1684 cgroup_addrm_files(&root->top_cgroup, cgroup_base_files, false);
1685 revert_creds(cred); 1685 revert_creds(cred);
1686 unlock_drop: 1686 unlock_drop:
1687 cgroup_exit_root_id(root); 1687 cgroup_exit_root_id(root);
@@ -2694,8 +2694,7 @@ static umode_t cgroup_file_mode(const struct cftype *cft)
2694 return mode; 2694 return mode;
2695} 2695}
2696 2696
2697static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, 2697static int cgroup_add_file(struct cgroup *cgrp, struct cftype *cft)
2698 struct cftype *cft)
2699{ 2698{
2700 struct dentry *dir = cgrp->dentry; 2699 struct dentry *dir = cgrp->dentry;
2701 struct cgroup *parent = __d_cgrp(dir); 2700 struct cgroup *parent = __d_cgrp(dir);
@@ -2705,8 +2704,8 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
2705 umode_t mode; 2704 umode_t mode;
2706 char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 }; 2705 char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 };
2707 2706
2708 if (subsys && !(cgrp->root->flags & CGRP_ROOT_NOPREFIX)) { 2707 if (cft->ss && !(cgrp->root->flags & CGRP_ROOT_NOPREFIX)) {
2709 strcpy(name, subsys->name); 2708 strcpy(name, cft->ss->name);
2710 strcat(name, "."); 2709 strcat(name, ".");
2711 } 2710 }
2712 strcat(name, cft->name); 2711 strcat(name, cft->name);
@@ -2743,17 +2742,16 @@ out:
2743/** 2742/**
2744 * cgroup_addrm_files - add or remove files to a cgroup directory 2743 * cgroup_addrm_files - add or remove files to a cgroup directory
2745 * @cgrp: the target cgroup 2744 * @cgrp: the target cgroup
2746 * @subsys: the subsystem of files to be added
2747 * @cfts: array of cftypes to be added 2745 * @cfts: array of cftypes to be added
2748 * @is_add: whether to add or remove 2746 * @is_add: whether to add or remove
2749 * 2747 *
2750 * Depending on @is_add, add or remove files defined by @cfts on @cgrp. 2748 * Depending on @is_add, add or remove files defined by @cfts on @cgrp.
2751 * All @cfts should belong to @subsys. For removals, this function never 2749 * For removals, this function never fails. If addition fails, this
2752 * fails. If addition fails, this function doesn't remove files already 2750 * function doesn't remove files already added. The caller is responsible
2753 * added. The caller is responsible for cleaning up. 2751 * for cleaning up.
2754 */ 2752 */
2755static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, 2753static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
2756 struct cftype cfts[], bool is_add) 2754 bool is_add)
2757{ 2755{
2758 struct cftype *cft; 2756 struct cftype *cft;
2759 int ret; 2757 int ret;
@@ -2771,7 +2769,7 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
2771 continue; 2769 continue;
2772 2770
2773 if (is_add) { 2771 if (is_add) {
2774 ret = cgroup_add_file(cgrp, subsys, cft); 2772 ret = cgroup_add_file(cgrp, cft);
2775 if (ret) { 2773 if (ret) {
2776 pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n", 2774 pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n",
2777 cft->name, ret); 2775 cft->name, ret);
@@ -2796,11 +2794,11 @@ static void cgroup_cfts_prepare(void)
2796 mutex_lock(&cgroup_mutex); 2794 mutex_lock(&cgroup_mutex);
2797} 2795}
2798 2796
2799static int cgroup_cfts_commit(struct cgroup_subsys *ss, 2797static int cgroup_cfts_commit(struct cftype *cfts, bool is_add)
2800 struct cftype *cfts, bool is_add)
2801 __releases(&cgroup_mutex) 2798 __releases(&cgroup_mutex)
2802{ 2799{
2803 LIST_HEAD(pending); 2800 LIST_HEAD(pending);
2801 struct cgroup_subsys *ss = cfts[0].ss;
2804 struct cgroup *cgrp, *root = &ss->root->top_cgroup; 2802 struct cgroup *cgrp, *root = &ss->root->top_cgroup;
2805 struct super_block *sb = ss->root->sb; 2803 struct super_block *sb = ss->root->sb;
2806 struct dentry *prev = NULL; 2804 struct dentry *prev = NULL;
@@ -2828,7 +2826,7 @@ static int cgroup_cfts_commit(struct cgroup_subsys *ss,
2828 inode = root->dentry->d_inode; 2826 inode = root->dentry->d_inode;
2829 mutex_lock(&inode->i_mutex); 2827 mutex_lock(&inode->i_mutex);
2830 mutex_lock(&cgroup_mutex); 2828 mutex_lock(&cgroup_mutex);
2831 ret = cgroup_addrm_files(root, ss, cfts, is_add); 2829 ret = cgroup_addrm_files(root, cfts, is_add);
2832 mutex_unlock(&cgroup_mutex); 2830 mutex_unlock(&cgroup_mutex);
2833 mutex_unlock(&inode->i_mutex); 2831 mutex_unlock(&inode->i_mutex);
2834 2832
@@ -2851,7 +2849,7 @@ static int cgroup_cfts_commit(struct cgroup_subsys *ss,
2851 mutex_lock(&inode->i_mutex); 2849 mutex_lock(&inode->i_mutex);
2852 mutex_lock(&cgroup_mutex); 2850 mutex_lock(&cgroup_mutex);
2853 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp)) 2851 if (cgrp->serial_nr < update_before && !cgroup_is_dead(cgrp))
2854 ret = cgroup_addrm_files(cgrp, ss, cfts, is_add); 2852 ret = cgroup_addrm_files(cgrp, cfts, is_add);
2855 mutex_unlock(&cgroup_mutex); 2853 mutex_unlock(&cgroup_mutex);
2856 mutex_unlock(&inode->i_mutex); 2854 mutex_unlock(&inode->i_mutex);
2857 2855
@@ -2883,51 +2881,56 @@ out_deact:
2883int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) 2881int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
2884{ 2882{
2885 struct cftype_set *set; 2883 struct cftype_set *set;
2884 struct cftype *cft;
2886 int ret; 2885 int ret;
2887 2886
2888 set = kzalloc(sizeof(*set), GFP_KERNEL); 2887 set = kzalloc(sizeof(*set), GFP_KERNEL);
2889 if (!set) 2888 if (!set)
2890 return -ENOMEM; 2889 return -ENOMEM;
2891 2890
2891 for (cft = cfts; cft->name[0] != '\0'; cft++)
2892 cft->ss = ss;
2893
2892 cgroup_cfts_prepare(); 2894 cgroup_cfts_prepare();
2893 set->cfts = cfts; 2895 set->cfts = cfts;
2894 list_add_tail(&set->node, &ss->cftsets); 2896 list_add_tail(&set->node, &ss->cftsets);
2895 ret = cgroup_cfts_commit(ss, cfts, true); 2897 ret = cgroup_cfts_commit(cfts, true);
2896 if (ret) 2898 if (ret)
2897 cgroup_rm_cftypes(ss, cfts); 2899 cgroup_rm_cftypes(cfts);
2898 return ret; 2900 return ret;
2899} 2901}
2900EXPORT_SYMBOL_GPL(cgroup_add_cftypes); 2902EXPORT_SYMBOL_GPL(cgroup_add_cftypes);
2901 2903
2902/** 2904/**
2903 * cgroup_rm_cftypes - remove an array of cftypes from a subsystem 2905 * cgroup_rm_cftypes - remove an array of cftypes from a subsystem
2904 * @ss: target cgroup subsystem
2905 * @cfts: zero-length name terminated array of cftypes 2906 * @cfts: zero-length name terminated array of cftypes
2906 * 2907 *
2907 * Unregister @cfts from @ss. Files described by @cfts are removed from 2908 * Unregister @cfts. Files described by @cfts are removed from all
2908 * all existing cgroups to which @ss is attached and all future cgroups 2909 * existing cgroups and all future cgroups won't have them either. This
2909 * won't have them either. This function can be called anytime whether @ss 2910 * function can be called anytime whether @cfts' subsys is attached or not.
2910 * is attached or not.
2911 * 2911 *
2912 * Returns 0 on successful unregistration, -ENOENT if @cfts is not 2912 * Returns 0 on successful unregistration, -ENOENT if @cfts is not
2913 * registered with @ss. 2913 * registered.
2914 */ 2914 */
2915int cgroup_rm_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) 2915int cgroup_rm_cftypes(struct cftype *cfts)
2916{ 2916{
2917 struct cftype_set *set; 2917 struct cftype_set *set;
2918 2918
2919 if (!cfts || !cfts[0].ss)
2920 return -ENOENT;
2921
2919 cgroup_cfts_prepare(); 2922 cgroup_cfts_prepare();
2920 2923
2921 list_for_each_entry(set, &ss->cftsets, node) { 2924 list_for_each_entry(set, &cfts[0].ss->cftsets, node) {
2922 if (set->cfts == cfts) { 2925 if (set->cfts == cfts) {
2923 list_del(&set->node); 2926 list_del(&set->node);
2924 kfree(set); 2927 kfree(set);
2925 cgroup_cfts_commit(ss, cfts, false); 2928 cgroup_cfts_commit(cfts, false);
2926 return 0; 2929 return 0;
2927 } 2930 }
2928 } 2931 }
2929 2932
2930 cgroup_cfts_commit(ss, NULL, false); 2933 cgroup_cfts_commit(NULL, false);
2931 return -ENOENT; 2934 return -ENOENT;
2932} 2935}
2933 2936
@@ -4148,7 +4151,7 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
4148 continue; 4151 continue;
4149 4152
4150 list_for_each_entry(set, &ss->cftsets, node) { 4153 list_for_each_entry(set, &ss->cftsets, node) {
4151 ret = cgroup_addrm_files(cgrp, ss, set->cfts, true); 4154 ret = cgroup_addrm_files(cgrp, set->cfts, true);
4152 if (ret < 0) 4155 if (ret < 0)
4153 goto err; 4156 goto err;
4154 } 4157 }
@@ -4377,7 +4380,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4377 4380
4378 idr_replace(&root->cgroup_idr, cgrp, cgrp->id); 4381 idr_replace(&root->cgroup_idr, cgrp, cgrp->id);
4379 4382
4380 err = cgroup_addrm_files(cgrp, NULL, cgroup_base_files, true); 4383 err = cgroup_addrm_files(cgrp, cgroup_base_files, true);
4381 if (err) 4384 if (err)
4382 goto err_destroy; 4385 goto err_destroy;
4383 4386
@@ -4538,7 +4541,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4538 * but we aren't quite done with @cgrp yet, so hold onto it. 4541 * but we aren't quite done with @cgrp yet, so hold onto it.
4539 */ 4542 */
4540 cgroup_clear_dir(cgrp, cgrp->root->subsys_mask); 4543 cgroup_clear_dir(cgrp, cgrp->root->subsys_mask);
4541 cgroup_addrm_files(cgrp, NULL, cgroup_base_files, false); 4544 cgroup_addrm_files(cgrp, cgroup_base_files, false);
4542 dget(d); 4545 dget(d);
4543 cgroup_d_remove_dir(d); 4546 cgroup_d_remove_dir(d);
4544 4547
@@ -4632,6 +4635,11 @@ static void __init_or_module cgroup_init_cftsets(struct cgroup_subsys *ss)
4632 * deregistration. 4635 * deregistration.
4633 */ 4636 */
4634 if (ss->base_cftypes) { 4637 if (ss->base_cftypes) {
4638 struct cftype *cft;
4639
4640 for (cft = ss->base_cftypes; cft->name[0] != '\0'; cft++)
4641 cft->ss = ss;
4642
4635 ss->base_cftset.cfts = ss->base_cftypes; 4643 ss->base_cftset.cfts = ss->base_cftypes;
4636 list_add_tail(&ss->base_cftset.node, &ss->cftsets); 4644 list_add_tail(&ss->base_cftset.node, &ss->cftsets);
4637 } 4645 }