aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-07-09 16:39:49 -0400
committerJens Axboe <axboe@fb.com>2015-07-09 16:41:09 -0400
commit7876f930d0e78addc6bbdbba0d6c196a0788d545 (patch)
tree3e38c6592038791cff22a9d3dd6b271c04333a58
parent144232b34258c1fc19729e077c6fb161e30da07b (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.c17
-rw-r--r--include/linux/blk-cgroup.h1
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
47static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS]; 47static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS];
48 48
49static LIST_HEAD(all_blkcgs); /* protected by blkcg_pol_mutex */
50
49static bool blkcg_policy_enabled(struct request_queue *q, 51static 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);
875done: 879done:
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
884free_pd_blkcg: 891free_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
888free_blkcg: 894free_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