diff options
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 202 |
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 |
1061 | static void cfq_update_blkio_group_weight(struct request_queue *q, | 1061 | static 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 | ||
1113 | static 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 | |||
1121 | static 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 | |||
1130 | static 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 | |||
1137 | static 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 | |||
1162 | static 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 | ||
1186 | static 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 */ | ||
1201 | static 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 | |||
1212 | static 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 */ |
1115 | static struct cfq_group *cfq_lookup_create_cfqg(struct cfq_data *cfqd, | 1311 | static 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 = { | |||
3715 | static struct blkio_policy_type blkio_policy_cfq = { | 3911 | static 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 | ||