diff options
author | Tejun Heo <tj@kernel.org> | 2015-07-09 16:39:49 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-07-09 16:41:09 -0400 |
commit | 7876f930d0e78addc6bbdbba0d6c196a0788d545 (patch) | |
tree | 3e38c6592038791cff22a9d3dd6b271c04333a58 | |
parent | 144232b34258c1fc19729e077c6fb161e30da07b (diff) |
blkcg: implement all_blkcgs list
Add all_blkcgs list goes through blkcg->all_blkcgs_node and is
protected by blkcg_pol_mutex. This will be used to fix
blkcg_policy_data allocation bug.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Arianna Avanzini <avanzini.arianna@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-cgroup.c | 17 | ||||
-rw-r--r-- | include/linux/blk-cgroup.h | 1 |
2 files changed, 13 insertions, 5 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 05b893de516b..42ff436ffaf4 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -46,6 +46,8 @@ struct cgroup_subsys_state * const blkcg_root_css = &blkcg_root.css; | |||
46 | 46 | ||
47 | static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS]; | 47 | static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS]; |
48 | 48 | ||
49 | static LIST_HEAD(all_blkcgs); /* protected by blkcg_pol_mutex */ | ||
50 | |||
49 | static bool blkcg_policy_enabled(struct request_queue *q, | 51 | static bool blkcg_policy_enabled(struct request_queue *q, |
50 | const struct blkcg_policy *pol) | 52 | const struct blkcg_policy *pol) |
51 | { | 53 | { |
@@ -817,6 +819,10 @@ static void blkcg_css_free(struct cgroup_subsys_state *css) | |||
817 | { | 819 | { |
818 | struct blkcg *blkcg = css_to_blkcg(css); | 820 | struct blkcg *blkcg = css_to_blkcg(css); |
819 | 821 | ||
822 | mutex_lock(&blkcg_pol_mutex); | ||
823 | list_del(&blkcg->all_blkcgs_node); | ||
824 | mutex_unlock(&blkcg_pol_mutex); | ||
825 | |||
820 | if (blkcg != &blkcg_root) { | 826 | if (blkcg != &blkcg_root) { |
821 | int i; | 827 | int i; |
822 | 828 | ||
@@ -833,6 +839,8 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | |||
833 | struct cgroup_subsys_state *ret; | 839 | struct cgroup_subsys_state *ret; |
834 | int i; | 840 | int i; |
835 | 841 | ||
842 | mutex_lock(&blkcg_pol_mutex); | ||
843 | |||
836 | if (!parent_css) { | 844 | if (!parent_css) { |
837 | blkcg = &blkcg_root; | 845 | blkcg = &blkcg_root; |
838 | goto done; | 846 | goto done; |
@@ -844,8 +852,6 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | |||
844 | goto free_blkcg; | 852 | goto free_blkcg; |
845 | } | 853 | } |
846 | 854 | ||
847 | mutex_lock(&blkcg_pol_mutex); | ||
848 | |||
849 | for (i = 0; i < BLKCG_MAX_POLS ; i++) { | 855 | for (i = 0; i < BLKCG_MAX_POLS ; i++) { |
850 | struct blkcg_policy *pol = blkcg_policy[i]; | 856 | struct blkcg_policy *pol = blkcg_policy[i]; |
851 | struct blkcg_policy_data *cpd; | 857 | struct blkcg_policy_data *cpd; |
@@ -862,7 +868,6 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | |||
862 | BUG_ON(blkcg->pd[i]); | 868 | BUG_ON(blkcg->pd[i]); |
863 | cpd = kzalloc(pol->cpd_size, GFP_KERNEL); | 869 | cpd = kzalloc(pol->cpd_size, GFP_KERNEL); |
864 | if (!cpd) { | 870 | if (!cpd) { |
865 | mutex_unlock(&blkcg_pol_mutex); | ||
866 | ret = ERR_PTR(-ENOMEM); | 871 | ret = ERR_PTR(-ENOMEM); |
867 | goto free_pd_blkcg; | 872 | goto free_pd_blkcg; |
868 | } | 873 | } |
@@ -871,7 +876,6 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) | |||
871 | pol->cpd_init_fn(blkcg); | 876 | pol->cpd_init_fn(blkcg); |
872 | } | 877 | } |
873 | 878 | ||
874 | mutex_unlock(&blkcg_pol_mutex); | ||
875 | done: | 879 | done: |
876 | spin_lock_init(&blkcg->lock); | 880 | spin_lock_init(&blkcg->lock); |
877 | INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_ATOMIC); | 881 | INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_ATOMIC); |
@@ -879,14 +883,17 @@ done: | |||
879 | #ifdef CONFIG_CGROUP_WRITEBACK | 883 | #ifdef CONFIG_CGROUP_WRITEBACK |
880 | INIT_LIST_HEAD(&blkcg->cgwb_list); | 884 | INIT_LIST_HEAD(&blkcg->cgwb_list); |
881 | #endif | 885 | #endif |
886 | list_add_tail(&blkcg->all_blkcgs_node, &all_blkcgs); | ||
887 | |||
888 | mutex_unlock(&blkcg_pol_mutex); | ||
882 | return &blkcg->css; | 889 | return &blkcg->css; |
883 | 890 | ||
884 | free_pd_blkcg: | 891 | free_pd_blkcg: |
885 | for (i--; i >= 0; i--) | 892 | for (i--; i >= 0; i--) |
886 | kfree(blkcg->pd[i]); | 893 | kfree(blkcg->pd[i]); |
887 | |||
888 | free_blkcg: | 894 | free_blkcg: |
889 | kfree(blkcg); | 895 | kfree(blkcg); |
896 | mutex_unlock(&blkcg_pol_mutex); | ||
890 | return ret; | 897 | return ret; |
891 | } | 898 | } |
892 | 899 | ||
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index 58cfab80dd70..cf3e7bc22ef3 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h | |||
@@ -47,6 +47,7 @@ struct blkcg { | |||
47 | 47 | ||
48 | struct blkcg_policy_data *pd[BLKCG_MAX_POLS]; | 48 | struct blkcg_policy_data *pd[BLKCG_MAX_POLS]; |
49 | 49 | ||
50 | struct list_head all_blkcgs_node; | ||
50 | #ifdef CONFIG_CGROUP_WRITEBACK | 51 | #ifdef CONFIG_CGROUP_WRITEBACK |
51 | struct list_head cgwb_list; | 52 | struct list_head cgwb_list; |
52 | #endif | 53 | #endif |