aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-04-01 17:38:43 -0400
committerTejun Heo <tj@kernel.org>2012-04-01 17:38:43 -0400
commit60c2bc2d5a12369deef395cda41638d7e6b6bf19 (patch)
tree67fb6ace87a930215f800f0a96bb33f9773231c7 /block/cfq-iosched.c
parent44ea53de46a8b01a65ae6217f47e00b516725190 (diff)
blkcg: move conf/stat file handling code to policies
blkcg conf/stat handling is convoluted in that details which belong to specific policy implementations are all out in blkcg core and then policies hook into core layer to access and manipulate confs and stats. This sadly achieves both inflexibility (confs/stats can't be modified without messing with blkcg core) and complexity (all the call-ins and call-backs). The previous patches restructured conf and stat handling code such that they can be separated out. This patch relocates the file handling part. All conf/stat file handling code which belongs to BLKIO_POLICY_PROP is moved to cfq-iosched.c and all BKLIO_POLICY_THROTL code to blk-throtl.c. The move is verbatim except for blkio_update_group_{weight|bps|iops}() callbacks which relays conf changes to policies. The configuration settings are handled in policies themselves so the relaying isn't necessary. Conf setting functions are modified to directly call per-policy update functions and the relaying mechanism is dropped. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c202
1 files changed, 199 insertions, 3 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 8cca6161d0b..119e061a767 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1058,8 +1058,7 @@ static void cfq_init_cfqg_base(struct cfq_group *cfqg)
1058} 1058}
1059 1059
1060#ifdef CONFIG_CFQ_GROUP_IOSCHED 1060#ifdef CONFIG_CFQ_GROUP_IOSCHED
1061static void cfq_update_blkio_group_weight(struct request_queue *q, 1061static void cfq_update_blkio_group_weight(struct blkio_group *blkg,
1062 struct blkio_group *blkg,
1063 unsigned int weight) 1062 unsigned int weight)
1064{ 1063{
1065 struct cfq_group *cfqg = blkg_to_cfqg(blkg); 1064 struct cfq_group *cfqg = blkg_to_cfqg(blkg);
@@ -1111,6 +1110,203 @@ static void cfq_link_cfqq_cfqg(struct cfq_queue *cfqq, struct cfq_group *cfqg)
1111 cfqg_get(cfqg); 1110 cfqg_get(cfqg);
1112} 1111}
1113 1112
1113static u64 blkg_prfill_weight_device(struct seq_file *sf,
1114 struct blkg_policy_data *pd, int off)
1115{
1116 if (!pd->conf.weight)
1117 return 0;
1118 return __blkg_prfill_u64(sf, pd, pd->conf.weight);
1119}
1120
1121static int blkcg_print_weight_device(struct cgroup *cgrp, struct cftype *cft,
1122 struct seq_file *sf)
1123{
1124 blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp),
1125 blkg_prfill_weight_device, BLKIO_POLICY_PROP, 0,
1126 false);
1127 return 0;
1128}
1129
1130static int blkcg_print_weight(struct cgroup *cgrp, struct cftype *cft,
1131 struct seq_file *sf)
1132{
1133 seq_printf(sf, "%u\n", cgroup_to_blkio_cgroup(cgrp)->weight);
1134 return 0;
1135}
1136
1137static int blkcg_set_weight_device(struct cgroup *cgrp, struct cftype *cft,
1138 const char *buf)
1139{
1140 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
1141 struct blkg_policy_data *pd;
1142 struct blkg_conf_ctx ctx;
1143 int ret;
1144
1145 ret = blkg_conf_prep(blkcg, buf, &ctx);
1146 if (ret)
1147 return ret;
1148
1149 ret = -EINVAL;
1150 pd = ctx.blkg->pd[BLKIO_POLICY_PROP];
1151 if (pd && (!ctx.v || (ctx.v >= BLKIO_WEIGHT_MIN &&
1152 ctx.v <= BLKIO_WEIGHT_MAX))) {
1153 pd->conf.weight = ctx.v;
1154 cfq_update_blkio_group_weight(ctx.blkg, ctx.v ?: blkcg->weight);
1155 ret = 0;
1156 }
1157
1158 blkg_conf_finish(&ctx);
1159 return ret;
1160}
1161
1162static int blkcg_set_weight(struct cgroup *cgrp, struct cftype *cft, u64 val)
1163{
1164 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
1165 struct blkio_group *blkg;
1166 struct hlist_node *n;
1167
1168 if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX)
1169 return -EINVAL;
1170
1171 spin_lock_irq(&blkcg->lock);
1172 blkcg->weight = (unsigned int)val;
1173
1174 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
1175 struct blkg_policy_data *pd = blkg->pd[BLKIO_POLICY_PROP];
1176
1177 if (pd && !pd->conf.weight)
1178 cfq_update_blkio_group_weight(blkg, blkcg->weight);
1179 }
1180
1181 spin_unlock_irq(&blkcg->lock);
1182 return 0;
1183}
1184
1185#ifdef CONFIG_DEBUG_BLK_CGROUP
1186static u64 blkg_prfill_avg_queue_size(struct seq_file *sf,
1187 struct blkg_policy_data *pd, int off)
1188{
1189 u64 samples = blkg_stat_read(&pd->stats.avg_queue_size_samples);
1190 u64 v = 0;
1191
1192 if (samples) {
1193 v = blkg_stat_read(&pd->stats.avg_queue_size_sum);
1194 do_div(v, samples);
1195 }
1196 __blkg_prfill_u64(sf, pd, v);
1197 return 0;
1198}
1199
1200/* print avg_queue_size */
1201static int blkcg_print_avg_queue_size(struct cgroup *cgrp, struct cftype *cft,
1202 struct seq_file *sf)
1203{
1204 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
1205
1206 blkcg_print_blkgs(sf, blkcg, blkg_prfill_avg_queue_size,
1207 BLKIO_POLICY_PROP, 0, false);
1208 return 0;
1209}
1210#endif /* CONFIG_DEBUG_BLK_CGROUP */
1211
1212static struct cftype cfq_blkcg_files[] = {
1213 {
1214 .name = "weight_device",
1215 .read_seq_string = blkcg_print_weight_device,
1216 .write_string = blkcg_set_weight_device,
1217 .max_write_len = 256,
1218 },
1219 {
1220 .name = "weight",
1221 .read_seq_string = blkcg_print_weight,
1222 .write_u64 = blkcg_set_weight,
1223 },
1224 {
1225 .name = "time",
1226 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1227 offsetof(struct blkio_group_stats, time)),
1228 .read_seq_string = blkcg_print_stat,
1229 },
1230 {
1231 .name = "sectors",
1232 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1233 offsetof(struct blkio_group_stats_cpu, sectors)),
1234 .read_seq_string = blkcg_print_cpu_stat,
1235 },
1236 {
1237 .name = "io_service_bytes",
1238 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1239 offsetof(struct blkio_group_stats_cpu, service_bytes)),
1240 .read_seq_string = blkcg_print_cpu_rwstat,
1241 },
1242 {
1243 .name = "io_serviced",
1244 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1245 offsetof(struct blkio_group_stats_cpu, serviced)),
1246 .read_seq_string = blkcg_print_cpu_rwstat,
1247 },
1248 {
1249 .name = "io_service_time",
1250 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1251 offsetof(struct blkio_group_stats, service_time)),
1252 .read_seq_string = blkcg_print_rwstat,
1253 },
1254 {
1255 .name = "io_wait_time",
1256 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1257 offsetof(struct blkio_group_stats, wait_time)),
1258 .read_seq_string = blkcg_print_rwstat,
1259 },
1260 {
1261 .name = "io_merged",
1262 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1263 offsetof(struct blkio_group_stats, merged)),
1264 .read_seq_string = blkcg_print_rwstat,
1265 },
1266 {
1267 .name = "io_queued",
1268 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1269 offsetof(struct blkio_group_stats, queued)),
1270 .read_seq_string = blkcg_print_rwstat,
1271 },
1272#ifdef CONFIG_DEBUG_BLK_CGROUP
1273 {
1274 .name = "avg_queue_size",
1275 .read_seq_string = blkcg_print_avg_queue_size,
1276 },
1277 {
1278 .name = "group_wait_time",
1279 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1280 offsetof(struct blkio_group_stats, group_wait_time)),
1281 .read_seq_string = blkcg_print_stat,
1282 },
1283 {
1284 .name = "idle_time",
1285 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1286 offsetof(struct blkio_group_stats, idle_time)),
1287 .read_seq_string = blkcg_print_stat,
1288 },
1289 {
1290 .name = "empty_time",
1291 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1292 offsetof(struct blkio_group_stats, empty_time)),
1293 .read_seq_string = blkcg_print_stat,
1294 },
1295 {
1296 .name = "dequeue",
1297 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1298 offsetof(struct blkio_group_stats, dequeue)),
1299 .read_seq_string = blkcg_print_stat,
1300 },
1301 {
1302 .name = "unaccounted_time",
1303 .private = BLKCG_STAT_PRIV(BLKIO_POLICY_PROP,
1304 offsetof(struct blkio_group_stats, unaccounted_time)),
1305 .read_seq_string = blkcg_print_stat,
1306 },
1307#endif /* CONFIG_DEBUG_BLK_CGROUP */
1308 { } /* terminate */
1309};
1114#else /* GROUP_IOSCHED */ 1310#else /* GROUP_IOSCHED */
1115static struct cfq_group *cfq_lookup_create_cfqg(struct cfq_data *cfqd, 1311static struct cfq_group *cfq_lookup_create_cfqg(struct cfq_data *cfqd,
1116 struct blkio_cgroup *blkcg) 1312 struct blkio_cgroup *blkcg)
@@ -3715,10 +3911,10 @@ static struct elevator_type iosched_cfq = {
3715static struct blkio_policy_type blkio_policy_cfq = { 3911static struct blkio_policy_type blkio_policy_cfq = {
3716 .ops = { 3912 .ops = {
3717 .blkio_init_group_fn = cfq_init_blkio_group, 3913 .blkio_init_group_fn = cfq_init_blkio_group,
3718 .blkio_update_group_weight_fn = cfq_update_blkio_group_weight,
3719 }, 3914 },
3720 .plid = BLKIO_POLICY_PROP, 3915 .plid = BLKIO_POLICY_PROP,
3721 .pdata_size = sizeof(struct cfq_group), 3916 .pdata_size = sizeof(struct cfq_group),
3917 .cftypes = cfq_blkcg_files,
3722}; 3918};
3723#endif 3919#endif
3724 3920