aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
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 8cca6161d0bc..119e061a7675 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