aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-08-18 17:55:16 -0400
committerJens Axboe <axboe@fb.com>2015-08-18 18:49:17 -0400
commite4a9bde9589fdc51283755cdd75d47b27ca7c6fb (patch)
treecc26b9cdba09e6571342f16182cafee5e82852b0
parent814376483e7d85b69a70634633f1f9d01c6ee0cf (diff)
blkcg: replace blkcg_policy->cpd_size with ->cpd_alloc/free_fn() methods
Each active policy has a cpd (blkcg_policy_data) on each blkcg. The cpd's were allocated by blkcg core and each policy could request to allocate extra space at the end by setting blkcg_policy->cpd_size larger than the size of cpd. This is a bit unusual but blkg (blkcg_gq) policy data used to be handled this way too so it made sense to be consistent; however, blkg policy data switched to alloc/free callbacks. This patch makes similar changes to cpd handling. blkcg_policy->cpd_alloc/free_fn() are added to replace ->cpd_size. As cpd allocation is now done from policy side, it can simply allocate a larger area which embeds cpd at the beginning. As ->cpd_alloc_fn() may be able to perform all necessary initializations, this patch makes ->cpd_init_fn() optional. 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.c39
-rw-r--r--block/cfq-iosched.c19
-rw-r--r--include/linux/blk-cgroup.h17
3 files changed, 52 insertions, 23 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 247c42c8c83b..2b4354b6b5de 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -817,11 +817,15 @@ static void blkcg_css_free(struct cgroup_subsys_state *css)
817 int i; 817 int i;
818 818
819 mutex_lock(&blkcg_pol_mutex); 819 mutex_lock(&blkcg_pol_mutex);
820
820 list_del(&blkcg->all_blkcgs_node); 821 list_del(&blkcg->all_blkcgs_node);
821 mutex_unlock(&blkcg_pol_mutex);
822 822
823 for (i = 0; i < BLKCG_MAX_POLS; i++) 823 for (i = 0; i < BLKCG_MAX_POLS; i++)
824 kfree(blkcg->cpd[i]); 824 if (blkcg->cpd[i])
825 blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]);
826
827 mutex_unlock(&blkcg_pol_mutex);
828
825 kfree(blkcg); 829 kfree(blkcg);
826} 830}
827 831
@@ -854,11 +858,10 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
854 * check if the policy requires any specific per-cgroup 858 * check if the policy requires any specific per-cgroup
855 * data: if it does, allocate and initialize it. 859 * data: if it does, allocate and initialize it.
856 */ 860 */
857 if (!pol || !pol->cpd_size) 861 if (!pol || !pol->cpd_alloc_fn)
858 continue; 862 continue;
859 863
860 BUG_ON(blkcg->cpd[i]); 864 cpd = pol->cpd_alloc_fn(GFP_KERNEL);
861 cpd = kzalloc(pol->cpd_size, GFP_KERNEL);
862 if (!cpd) { 865 if (!cpd) {
863 ret = ERR_PTR(-ENOMEM); 866 ret = ERR_PTR(-ENOMEM);
864 goto free_pd_blkcg; 867 goto free_pd_blkcg;
@@ -866,7 +869,8 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
866 blkcg->cpd[i] = cpd; 869 blkcg->cpd[i] = cpd;
867 cpd->blkcg = blkcg; 870 cpd->blkcg = blkcg;
868 cpd->plid = i; 871 cpd->plid = i;
869 pol->cpd_init_fn(cpd); 872 if (pol->cpd_init_fn)
873 pol->cpd_init_fn(cpd);
870 } 874 }
871 875
872 spin_lock_init(&blkcg->lock); 876 spin_lock_init(&blkcg->lock);
@@ -882,7 +886,8 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
882 886
883free_pd_blkcg: 887free_pd_blkcg:
884 for (i--; i >= 0; i--) 888 for (i--; i >= 0; i--)
885 kfree(blkcg->cpd[i]); 889 if (blkcg->cpd[i])
890 blkcg_policy[i]->cpd_free_fn(blkcg->cpd[i]);
886free_blkcg: 891free_blkcg:
887 kfree(blkcg); 892 kfree(blkcg);
888 mutex_unlock(&blkcg_pol_mutex); 893 mutex_unlock(&blkcg_pol_mutex);
@@ -1159,11 +1164,11 @@ int blkcg_policy_register(struct blkcg_policy *pol)
1159 blkcg_policy[pol->plid] = pol; 1164 blkcg_policy[pol->plid] = pol;
1160 1165
1161 /* allocate and install cpd's */ 1166 /* allocate and install cpd's */
1162 if (pol->cpd_size) { 1167 if (pol->cpd_alloc_fn) {
1163 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) { 1168 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
1164 struct blkcg_policy_data *cpd; 1169 struct blkcg_policy_data *cpd;
1165 1170
1166 cpd = kzalloc(pol->cpd_size, GFP_KERNEL); 1171 cpd = pol->cpd_alloc_fn(GFP_KERNEL);
1167 if (!cpd) { 1172 if (!cpd) {
1168 mutex_unlock(&blkcg_pol_mutex); 1173 mutex_unlock(&blkcg_pol_mutex);
1169 goto err_free_cpds; 1174 goto err_free_cpds;
@@ -1186,10 +1191,12 @@ int blkcg_policy_register(struct blkcg_policy *pol)
1186 return 0; 1191 return 0;
1187 1192
1188err_free_cpds: 1193err_free_cpds:
1189 if (pol->cpd_size) { 1194 if (pol->cpd_alloc_fn) {
1190 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) { 1195 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
1191 kfree(blkcg->cpd[pol->plid]); 1196 if (blkcg->cpd[pol->plid]) {
1192 blkcg->cpd[pol->plid] = NULL; 1197 pol->cpd_free_fn(blkcg->cpd[pol->plid]);
1198 blkcg->cpd[pol->plid] = NULL;
1199 }
1193 } 1200 }
1194 } 1201 }
1195 blkcg_policy[pol->plid] = NULL; 1202 blkcg_policy[pol->plid] = NULL;
@@ -1222,10 +1229,12 @@ void blkcg_policy_unregister(struct blkcg_policy *pol)
1222 /* remove cpds and unregister */ 1229 /* remove cpds and unregister */
1223 mutex_lock(&blkcg_pol_mutex); 1230 mutex_lock(&blkcg_pol_mutex);
1224 1231
1225 if (pol->cpd_size) { 1232 if (pol->cpd_alloc_fn) {
1226 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) { 1233 list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
1227 kfree(blkcg->cpd[pol->plid]); 1234 if (blkcg->cpd[pol->plid]) {
1228 blkcg->cpd[pol->plid] = NULL; 1235 pol->cpd_free_fn(blkcg->cpd[pol->plid]);
1236 blkcg->cpd[pol->plid] = NULL;
1237 }
1229 } 1238 }
1230 } 1239 }
1231 blkcg_policy[pol->plid] = NULL; 1240 blkcg_policy[pol->plid] = NULL;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index dd6ea9ee6245..a4429b366820 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1568,6 +1568,16 @@ static void cfqg_stats_init(struct cfqg_stats *stats)
1568#endif 1568#endif
1569} 1569}
1570 1570
1571static struct blkcg_policy_data *cfq_cpd_alloc(gfp_t gfp)
1572{
1573 struct cfq_group_data *cgd;
1574
1575 cgd = kzalloc(sizeof(*cgd), GFP_KERNEL);
1576 if (!cgd)
1577 return NULL;
1578 return &cgd->cpd;
1579}
1580
1571static void cfq_cpd_init(struct blkcg_policy_data *cpd) 1581static void cfq_cpd_init(struct blkcg_policy_data *cpd)
1572{ 1582{
1573 struct cfq_group_data *cgd = cpd_to_cfqgd(cpd); 1583 struct cfq_group_data *cgd = cpd_to_cfqgd(cpd);
@@ -1581,6 +1591,11 @@ static void cfq_cpd_init(struct blkcg_policy_data *cpd)
1581 } 1591 }
1582} 1592}
1583 1593
1594static void cfq_cpd_free(struct blkcg_policy_data *cpd)
1595{
1596 kfree(cpd_to_cfqgd(cpd));
1597}
1598
1584static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node) 1599static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node)
1585{ 1600{
1586 struct cfq_group *cfqg; 1601 struct cfq_group *cfqg;
@@ -4649,10 +4664,12 @@ static struct elevator_type iosched_cfq = {
4649 4664
4650#ifdef CONFIG_CFQ_GROUP_IOSCHED 4665#ifdef CONFIG_CFQ_GROUP_IOSCHED
4651static struct blkcg_policy blkcg_policy_cfq = { 4666static struct blkcg_policy blkcg_policy_cfq = {
4652 .cpd_size = sizeof(struct cfq_group_data),
4653 .cftypes = cfq_blkcg_files, 4667 .cftypes = cfq_blkcg_files,
4654 4668
4669 .cpd_alloc_fn = cfq_cpd_alloc,
4655 .cpd_init_fn = cfq_cpd_init, 4670 .cpd_init_fn = cfq_cpd_init,
4671 .cpd_free_fn = cfq_cpd_free,
4672
4656 .pd_alloc_fn = cfq_pd_alloc, 4673 .pd_alloc_fn = cfq_pd_alloc,
4657 .pd_init_fn = cfq_pd_init, 4674 .pd_init_fn = cfq_pd_init,
4658 .pd_offline_fn = cfq_pd_offline, 4675 .pd_offline_fn = cfq_pd_offline,
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index 7988d4749fff..15f2382bc723 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -81,11 +81,11 @@ struct blkg_policy_data {
81}; 81};
82 82
83/* 83/*
84 * Policies that need to keep per-blkcg data which is independent 84 * Policies that need to keep per-blkcg data which is independent from any
85 * from any request_queue associated to it must specify its size 85 * request_queue associated to it should implement cpd_alloc/free_fn()
86 * with the cpd_size field of the blkcg_policy structure and 86 * methods. A policy can allocate private data area by allocating larger
87 * embed a blkcg_policy_data in it. cpd_init() is invoked to let 87 * data structure which embeds blkcg_policy_data at the beginning.
88 * each policy handle per-blkcg data. 88 * cpd_init() is invoked to let each policy handle per-blkcg data.
89 */ 89 */
90struct blkcg_policy_data { 90struct blkcg_policy_data {
91 /* the blkcg and policy id this per-policy data belongs to */ 91 /* the blkcg and policy id this per-policy data belongs to */
@@ -124,7 +124,9 @@ struct blkcg_gq {
124 struct rcu_head rcu_head; 124 struct rcu_head rcu_head;
125}; 125};
126 126
127typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
127typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd); 128typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
129typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
128typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node); 130typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node);
129typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd); 131typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
130typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd); 132typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd);
@@ -134,13 +136,14 @@ typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkg_policy_data *pd);
134 136
135struct blkcg_policy { 137struct blkcg_policy {
136 int plid; 138 int plid;
137 /* policy specific per-blkcg data size */
138 size_t cpd_size;
139 /* cgroup files for the policy */ 139 /* cgroup files for the policy */
140 struct cftype *cftypes; 140 struct cftype *cftypes;
141 141
142 /* operations */ 142 /* operations */
143 blkcg_pol_alloc_cpd_fn *cpd_alloc_fn;
143 blkcg_pol_init_cpd_fn *cpd_init_fn; 144 blkcg_pol_init_cpd_fn *cpd_init_fn;
145 blkcg_pol_free_cpd_fn *cpd_free_fn;
146
144 blkcg_pol_alloc_pd_fn *pd_alloc_fn; 147 blkcg_pol_alloc_pd_fn *pd_alloc_fn;
145 blkcg_pol_init_pd_fn *pd_init_fn; 148 blkcg_pol_init_pd_fn *pd_init_fn;
146 blkcg_pol_online_pd_fn *pd_online_fn; 149 blkcg_pol_online_pd_fn *pd_online_fn;