Skip to content

Commit e4a9bde

Browse files
htejunaxboe
authored andcommitted
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 <[email protected]> Cc: Vivek Goyal <[email protected]> Cc: Arianna Avanzini <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 8143764 commit e4a9bde

File tree

3 files changed

+52
-23
lines changed

3 files changed

+52
-23
lines changed

block/blk-cgroup.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -817,11 +817,15 @@ static void blkcg_css_free(struct cgroup_subsys_state *css)
817817
int i;
818818

819819
mutex_lock(&blkcg_pol_mutex);
820+
820821
list_del(&blkcg->all_blkcgs_node);
821-
mutex_unlock(&blkcg_pol_mutex);
822822

823823
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+
825829
kfree(blkcg);
826830
}
827831

@@ -854,19 +858,19 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
854858
* check if the policy requires any specific per-cgroup
855859
* data: if it does, allocate and initialize it.
856860
*/
857-
if (!pol || !pol->cpd_size)
861+
if (!pol || !pol->cpd_alloc_fn)
858862
continue;
859863

860-
BUG_ON(blkcg->cpd[i]);
861-
cpd = kzalloc(pol->cpd_size, GFP_KERNEL);
864+
cpd = pol->cpd_alloc_fn(GFP_KERNEL);
862865
if (!cpd) {
863866
ret = ERR_PTR(-ENOMEM);
864867
goto free_pd_blkcg;
865868
}
866869
blkcg->cpd[i] = cpd;
867870
cpd->blkcg = blkcg;
868871
cpd->plid = i;
869-
pol->cpd_init_fn(cpd);
872+
if (pol->cpd_init_fn)
873+
pol->cpd_init_fn(cpd);
870874
}
871875

872876
spin_lock_init(&blkcg->lock);
@@ -882,7 +886,8 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
882886

883887
free_pd_blkcg:
884888
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]);
886891
free_blkcg:
887892
kfree(blkcg);
888893
mutex_unlock(&blkcg_pol_mutex);
@@ -1159,11 +1164,11 @@ int blkcg_policy_register(struct blkcg_policy *pol)
11591164
blkcg_policy[pol->plid] = pol;
11601165

11611166
/* allocate and install cpd's */
1162-
if (pol->cpd_size) {
1167+
if (pol->cpd_alloc_fn) {
11631168
list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
11641169
struct blkcg_policy_data *cpd;
11651170

1166-
cpd = kzalloc(pol->cpd_size, GFP_KERNEL);
1171+
cpd = pol->cpd_alloc_fn(GFP_KERNEL);
11671172
if (!cpd) {
11681173
mutex_unlock(&blkcg_pol_mutex);
11691174
goto err_free_cpds;
@@ -1186,10 +1191,12 @@ int blkcg_policy_register(struct blkcg_policy *pol)
11861191
return 0;
11871192

11881193
err_free_cpds:
1189-
if (pol->cpd_size) {
1194+
if (pol->cpd_alloc_fn) {
11901195
list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
1191-
kfree(blkcg->cpd[pol->plid]);
1192-
blkcg->cpd[pol->plid] = NULL;
1196+
if (blkcg->cpd[pol->plid]) {
1197+
pol->cpd_free_fn(blkcg->cpd[pol->plid]);
1198+
blkcg->cpd[pol->plid] = NULL;
1199+
}
11931200
}
11941201
}
11951202
blkcg_policy[pol->plid] = NULL;
@@ -1222,10 +1229,12 @@ void blkcg_policy_unregister(struct blkcg_policy *pol)
12221229
/* remove cpds and unregister */
12231230
mutex_lock(&blkcg_pol_mutex);
12241231

1225-
if (pol->cpd_size) {
1232+
if (pol->cpd_alloc_fn) {
12261233
list_for_each_entry(blkcg, &all_blkcgs, all_blkcgs_node) {
1227-
kfree(blkcg->cpd[pol->plid]);
1228-
blkcg->cpd[pol->plid] = NULL;
1234+
if (blkcg->cpd[pol->plid]) {
1235+
pol->cpd_free_fn(blkcg->cpd[pol->plid]);
1236+
blkcg->cpd[pol->plid] = NULL;
1237+
}
12291238
}
12301239
}
12311240
blkcg_policy[pol->plid] = NULL;

block/cfq-iosched.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,16 @@ static void cfqg_stats_init(struct cfqg_stats *stats)
15681568
#endif
15691569
}
15701570

1571+
static 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+
15711581
static void cfq_cpd_init(struct blkcg_policy_data *cpd)
15721582
{
15731583
struct cfq_group_data *cgd = cpd_to_cfqgd(cpd);
@@ -1581,6 +1591,11 @@ static void cfq_cpd_init(struct blkcg_policy_data *cpd)
15811591
}
15821592
}
15831593

1594+
static void cfq_cpd_free(struct blkcg_policy_data *cpd)
1595+
{
1596+
kfree(cpd_to_cfqgd(cpd));
1597+
}
1598+
15841599
static struct blkg_policy_data *cfq_pd_alloc(gfp_t gfp, int node)
15851600
{
15861601
struct cfq_group *cfqg;
@@ -4649,10 +4664,12 @@ static struct elevator_type iosched_cfq = {
46494664

46504665
#ifdef CONFIG_CFQ_GROUP_IOSCHED
46514666
static struct blkcg_policy blkcg_policy_cfq = {
4652-
.cpd_size = sizeof(struct cfq_group_data),
46534667
.cftypes = cfq_blkcg_files,
46544668

4669+
.cpd_alloc_fn = cfq_cpd_alloc,
46554670
.cpd_init_fn = cfq_cpd_init,
4671+
.cpd_free_fn = cfq_cpd_free,
4672+
46564673
.pd_alloc_fn = cfq_pd_alloc,
46574674
.pd_init_fn = cfq_pd_init,
46584675
.pd_offline_fn = cfq_pd_offline,

include/linux/blk-cgroup.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ struct blkg_policy_data {
8181
};
8282

8383
/*
84-
* Policies that need to keep per-blkcg data which is independent
85-
* from any request_queue associated to it must specify its size
86-
* with the cpd_size field of the blkcg_policy structure and
87-
* embed a blkcg_policy_data in it. cpd_init() is invoked to let
88-
* each policy handle per-blkcg data.
84+
* Policies that need to keep per-blkcg data which is independent from any
85+
* request_queue associated to it should implement cpd_alloc/free_fn()
86+
* methods. A policy can allocate private data area by allocating larger
87+
* data structure which embeds blkcg_policy_data at the beginning.
88+
* cpd_init() is invoked to let each policy handle per-blkcg data.
8989
*/
9090
struct blkcg_policy_data {
9191
/* the blkcg and policy id this per-policy data belongs to */
@@ -124,7 +124,9 @@ struct blkcg_gq {
124124
struct rcu_head rcu_head;
125125
};
126126

127+
typedef struct blkcg_policy_data *(blkcg_pol_alloc_cpd_fn)(gfp_t gfp);
127128
typedef void (blkcg_pol_init_cpd_fn)(struct blkcg_policy_data *cpd);
129+
typedef void (blkcg_pol_free_cpd_fn)(struct blkcg_policy_data *cpd);
128130
typedef struct blkg_policy_data *(blkcg_pol_alloc_pd_fn)(gfp_t gfp, int node);
129131
typedef void (blkcg_pol_init_pd_fn)(struct blkg_policy_data *pd);
130132
typedef 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);
134136

135137
struct blkcg_policy {
136138
int plid;
137-
/* policy specific per-blkcg data size */
138-
size_t cpd_size;
139139
/* cgroup files for the policy */
140140
struct cftype *cftypes;
141141

142142
/* operations */
143+
blkcg_pol_alloc_cpd_fn *cpd_alloc_fn;
143144
blkcg_pol_init_cpd_fn *cpd_init_fn;
145+
blkcg_pol_free_cpd_fn *cpd_free_fn;
146+
144147
blkcg_pol_alloc_pd_fn *pd_alloc_fn;
145148
blkcg_pol_init_pd_fn *pd_init_fn;
146149
blkcg_pol_online_pd_fn *pd_online_fn;

0 commit comments

Comments
 (0)