summaryrefslogtreecommitdiffstats
path: root/block/blk-cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r--block/blk-cgroup.c200
1 files changed, 162 insertions, 38 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 471fdcc5df85..07371cfdfae6 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -385,25 +385,40 @@ void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time,
385 385
386 spin_lock_irqsave(&blkg->stats_lock, flags); 386 spin_lock_irqsave(&blkg->stats_lock, flags);
387 blkg->stats.time += time; 387 blkg->stats.time += time;
388#ifdef CONFIG_DEBUG_BLK_CGROUP
388 blkg->stats.unaccounted_time += unaccounted_time; 389 blkg->stats.unaccounted_time += unaccounted_time;
390#endif
389 spin_unlock_irqrestore(&blkg->stats_lock, flags); 391 spin_unlock_irqrestore(&blkg->stats_lock, flags);
390} 392}
391EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used); 393EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used);
392 394
395/*
396 * should be called under rcu read lock or queue lock to make sure blkg pointer
397 * is valid.
398 */
393void blkiocg_update_dispatch_stats(struct blkio_group *blkg, 399void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
394 uint64_t bytes, bool direction, bool sync) 400 uint64_t bytes, bool direction, bool sync)
395{ 401{
396 struct blkio_group_stats *stats; 402 struct blkio_group_stats_cpu *stats_cpu;
397 unsigned long flags; 403 unsigned long flags;
398 404
399 spin_lock_irqsave(&blkg->stats_lock, flags); 405 /*
400 stats = &blkg->stats; 406 * Disabling interrupts to provide mutual exclusion between two
401 stats->sectors += bytes >> 9; 407 * writes on same cpu. It probably is not needed for 64bit. Not
402 blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICED], 1, direction, 408 * optimizing that case yet.
403 sync); 409 */
404 blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICE_BYTES], bytes, 410 local_irq_save(flags);
405 direction, sync); 411
406 spin_unlock_irqrestore(&blkg->stats_lock, flags); 412 stats_cpu = this_cpu_ptr(blkg->stats_cpu);
413
414 u64_stats_update_begin(&stats_cpu->syncp);
415 stats_cpu->sectors += bytes >> 9;
416 blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICED],
417 1, direction, sync);
418 blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICE_BYTES],
419 bytes, direction, sync);
420 u64_stats_update_end(&stats_cpu->syncp);
421 local_irq_restore(flags);
407} 422}
408EXPORT_SYMBOL_GPL(blkiocg_update_dispatch_stats); 423EXPORT_SYMBOL_GPL(blkiocg_update_dispatch_stats);
409 424
@@ -426,18 +441,44 @@ void blkiocg_update_completion_stats(struct blkio_group *blkg,
426} 441}
427EXPORT_SYMBOL_GPL(blkiocg_update_completion_stats); 442EXPORT_SYMBOL_GPL(blkiocg_update_completion_stats);
428 443
444/* Merged stats are per cpu. */
429void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction, 445void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
430 bool sync) 446 bool sync)
431{ 447{
448 struct blkio_group_stats_cpu *stats_cpu;
432 unsigned long flags; 449 unsigned long flags;
433 450
434 spin_lock_irqsave(&blkg->stats_lock, flags); 451 /*
435 blkio_add_stat(blkg->stats.stat_arr[BLKIO_STAT_MERGED], 1, direction, 452 * Disabling interrupts to provide mutual exclusion between two
436 sync); 453 * writes on same cpu. It probably is not needed for 64bit. Not
437 spin_unlock_irqrestore(&blkg->stats_lock, flags); 454 * optimizing that case yet.
455 */
456 local_irq_save(flags);
457
458 stats_cpu = this_cpu_ptr(blkg->stats_cpu);
459
460 u64_stats_update_begin(&stats_cpu->syncp);
461 blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_MERGED], 1,
462 direction, sync);
463 u64_stats_update_end(&stats_cpu->syncp);
464 local_irq_restore(flags);
438} 465}
439EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats); 466EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats);
440 467
468/*
469 * This function allocates the per cpu stats for blkio_group. Should be called
470 * from sleepable context as alloc_per_cpu() requires that.
471 */
472int blkio_alloc_blkg_stats(struct blkio_group *blkg)
473{
474 /* Allocate memory for per cpu stats */
475 blkg->stats_cpu = alloc_percpu(struct blkio_group_stats_cpu);
476 if (!blkg->stats_cpu)
477 return -ENOMEM;
478 return 0;
479}
480EXPORT_SYMBOL_GPL(blkio_alloc_blkg_stats);
481
441void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, 482void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
442 struct blkio_group *blkg, void *key, dev_t dev, 483 struct blkio_group *blkg, void *key, dev_t dev,
443 enum blkio_policy_id plid) 484 enum blkio_policy_id plid)
@@ -508,6 +549,30 @@ struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key)
508} 549}
509EXPORT_SYMBOL_GPL(blkiocg_lookup_group); 550EXPORT_SYMBOL_GPL(blkiocg_lookup_group);
510 551
552static void blkio_reset_stats_cpu(struct blkio_group *blkg)
553{
554 struct blkio_group_stats_cpu *stats_cpu;
555 int i, j, k;
556 /*
557 * Note: On 64 bit arch this should not be an issue. This has the
558 * possibility of returning some inconsistent value on 32bit arch
559 * as 64bit update on 32bit is non atomic. Taking care of this
560 * corner case makes code very complicated, like sending IPIs to
561 * cpus, taking care of stats of offline cpus etc.
562 *
563 * reset stats is anyway more of a debug feature and this sounds a
564 * corner case. So I am not complicating the code yet until and
565 * unless this becomes a real issue.
566 */
567 for_each_possible_cpu(i) {
568 stats_cpu = per_cpu_ptr(blkg->stats_cpu, i);
569 stats_cpu->sectors = 0;
570 for(j = 0; j < BLKIO_STAT_CPU_NR; j++)
571 for (k = 0; k < BLKIO_STAT_TOTAL; k++)
572 stats_cpu->stat_arr_cpu[j][k] = 0;
573 }
574}
575
511static int 576static int
512blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) 577blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val)
513{ 578{
@@ -552,7 +617,11 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val)
552 } 617 }
553#endif 618#endif
554 spin_unlock(&blkg->stats_lock); 619 spin_unlock(&blkg->stats_lock);
620
621 /* Reset Per cpu stats which don't take blkg->stats_lock */
622 blkio_reset_stats_cpu(blkg);
555 } 623 }
624
556 spin_unlock_irq(&blkcg->lock); 625 spin_unlock_irq(&blkcg->lock);
557 return 0; 626 return 0;
558} 627}
@@ -598,6 +667,59 @@ static uint64_t blkio_fill_stat(char *str, int chars_left, uint64_t val,
598 return val; 667 return val;
599} 668}
600 669
670
671static uint64_t blkio_read_stat_cpu(struct blkio_group *blkg,
672 enum stat_type_cpu type, enum stat_sub_type sub_type)
673{
674 int cpu;
675 struct blkio_group_stats_cpu *stats_cpu;
676 u64 val = 0, tval;
677
678 for_each_possible_cpu(cpu) {
679 unsigned int start;
680 stats_cpu = per_cpu_ptr(blkg->stats_cpu, cpu);
681
682 do {
683 start = u64_stats_fetch_begin(&stats_cpu->syncp);
684 if (type == BLKIO_STAT_CPU_SECTORS)
685 tval = stats_cpu->sectors;
686 else
687 tval = stats_cpu->stat_arr_cpu[type][sub_type];
688 } while(u64_stats_fetch_retry(&stats_cpu->syncp, start));
689
690 val += tval;
691 }
692
693 return val;
694}
695
696static uint64_t blkio_get_stat_cpu(struct blkio_group *blkg,
697 struct cgroup_map_cb *cb, dev_t dev, enum stat_type_cpu type)
698{
699 uint64_t disk_total, val;
700 char key_str[MAX_KEY_LEN];
701 enum stat_sub_type sub_type;
702
703 if (type == BLKIO_STAT_CPU_SECTORS) {
704 val = blkio_read_stat_cpu(blkg, type, 0);
705 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, val, cb, dev);
706 }
707
708 for (sub_type = BLKIO_STAT_READ; sub_type < BLKIO_STAT_TOTAL;
709 sub_type++) {
710 blkio_get_key_name(sub_type, dev, key_str, MAX_KEY_LEN, false);
711 val = blkio_read_stat_cpu(blkg, type, sub_type);
712 cb->fill(cb, key_str, val);
713 }
714
715 disk_total = blkio_read_stat_cpu(blkg, type, BLKIO_STAT_READ) +
716 blkio_read_stat_cpu(blkg, type, BLKIO_STAT_WRITE);
717
718 blkio_get_key_name(BLKIO_STAT_TOTAL, dev, key_str, MAX_KEY_LEN, false);
719 cb->fill(cb, key_str, disk_total);
720 return disk_total;
721}
722
601/* This should be called with blkg->stats_lock held */ 723/* This should be called with blkg->stats_lock held */
602static uint64_t blkio_get_stat(struct blkio_group *blkg, 724static uint64_t blkio_get_stat(struct blkio_group *blkg,
603 struct cgroup_map_cb *cb, dev_t dev, enum stat_type type) 725 struct cgroup_map_cb *cb, dev_t dev, enum stat_type type)
@@ -609,9 +731,6 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg,
609 if (type == BLKIO_STAT_TIME) 731 if (type == BLKIO_STAT_TIME)
610 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, 732 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
611 blkg->stats.time, cb, dev); 733 blkg->stats.time, cb, dev);
612 if (type == BLKIO_STAT_SECTORS)
613 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
614 blkg->stats.sectors, cb, dev);
615#ifdef CONFIG_DEBUG_BLK_CGROUP 734#ifdef CONFIG_DEBUG_BLK_CGROUP
616 if (type == BLKIO_STAT_UNACCOUNTED_TIME) 735 if (type == BLKIO_STAT_UNACCOUNTED_TIME)
617 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, 736 return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
@@ -1075,8 +1194,8 @@ static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft,
1075} 1194}
1076 1195
1077static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg, 1196static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg,
1078 struct cftype *cft, struct cgroup_map_cb *cb, enum stat_type type, 1197 struct cftype *cft, struct cgroup_map_cb *cb,
1079 bool show_total) 1198 enum stat_type type, bool show_total, bool pcpu)
1080{ 1199{
1081 struct blkio_group *blkg; 1200 struct blkio_group *blkg;
1082 struct hlist_node *n; 1201 struct hlist_node *n;
@@ -1087,10 +1206,15 @@ static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg,
1087 if (blkg->dev) { 1206 if (blkg->dev) {
1088 if (!cftype_blkg_same_policy(cft, blkg)) 1207 if (!cftype_blkg_same_policy(cft, blkg))
1089 continue; 1208 continue;
1090 spin_lock_irq(&blkg->stats_lock); 1209 if (pcpu)
1091 cgroup_total += blkio_get_stat(blkg, cb, blkg->dev, 1210 cgroup_total += blkio_get_stat_cpu(blkg, cb,
1092 type); 1211 blkg->dev, type);
1093 spin_unlock_irq(&blkg->stats_lock); 1212 else {
1213 spin_lock_irq(&blkg->stats_lock);
1214 cgroup_total += blkio_get_stat(blkg, cb,
1215 blkg->dev, type);
1216 spin_unlock_irq(&blkg->stats_lock);
1217 }
1094 } 1218 }
1095 } 1219 }
1096 if (show_total) 1220 if (show_total)
@@ -1114,47 +1238,47 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft,
1114 switch(name) { 1238 switch(name) {
1115 case BLKIO_PROP_time: 1239 case BLKIO_PROP_time:
1116 return blkio_read_blkg_stats(blkcg, cft, cb, 1240 return blkio_read_blkg_stats(blkcg, cft, cb,
1117 BLKIO_STAT_TIME, 0); 1241 BLKIO_STAT_TIME, 0, 0);
1118 case BLKIO_PROP_sectors: 1242 case BLKIO_PROP_sectors:
1119 return blkio_read_blkg_stats(blkcg, cft, cb, 1243 return blkio_read_blkg_stats(blkcg, cft, cb,
1120 BLKIO_STAT_SECTORS, 0); 1244 BLKIO_STAT_CPU_SECTORS, 0, 1);
1121 case BLKIO_PROP_io_service_bytes: 1245 case BLKIO_PROP_io_service_bytes:
1122 return blkio_read_blkg_stats(blkcg, cft, cb, 1246 return blkio_read_blkg_stats(blkcg, cft, cb,
1123 BLKIO_STAT_SERVICE_BYTES, 1); 1247 BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1);
1124 case BLKIO_PROP_io_serviced: 1248 case BLKIO_PROP_io_serviced:
1125 return blkio_read_blkg_stats(blkcg, cft, cb, 1249 return blkio_read_blkg_stats(blkcg, cft, cb,
1126 BLKIO_STAT_SERVICED, 1); 1250 BLKIO_STAT_CPU_SERVICED, 1, 1);
1127 case BLKIO_PROP_io_service_time: 1251 case BLKIO_PROP_io_service_time:
1128 return blkio_read_blkg_stats(blkcg, cft, cb, 1252 return blkio_read_blkg_stats(blkcg, cft, cb,
1129 BLKIO_STAT_SERVICE_TIME, 1); 1253 BLKIO_STAT_SERVICE_TIME, 1, 0);
1130 case BLKIO_PROP_io_wait_time: 1254 case BLKIO_PROP_io_wait_time:
1131 return blkio_read_blkg_stats(blkcg, cft, cb, 1255 return blkio_read_blkg_stats(blkcg, cft, cb,
1132 BLKIO_STAT_WAIT_TIME, 1); 1256 BLKIO_STAT_WAIT_TIME, 1, 0);
1133 case BLKIO_PROP_io_merged: 1257 case BLKIO_PROP_io_merged:
1134 return blkio_read_blkg_stats(blkcg, cft, cb, 1258 return blkio_read_blkg_stats(blkcg, cft, cb,
1135 BLKIO_STAT_MERGED, 1); 1259 BLKIO_STAT_CPU_MERGED, 1, 1);
1136 case BLKIO_PROP_io_queued: 1260 case BLKIO_PROP_io_queued:
1137 return blkio_read_blkg_stats(blkcg, cft, cb, 1261 return blkio_read_blkg_stats(blkcg, cft, cb,
1138 BLKIO_STAT_QUEUED, 1); 1262 BLKIO_STAT_QUEUED, 1, 0);
1139#ifdef CONFIG_DEBUG_BLK_CGROUP 1263#ifdef CONFIG_DEBUG_BLK_CGROUP
1140 case BLKIO_PROP_unaccounted_time: 1264 case BLKIO_PROP_unaccounted_time:
1141 return blkio_read_blkg_stats(blkcg, cft, cb, 1265 return blkio_read_blkg_stats(blkcg, cft, cb,
1142 BLKIO_STAT_UNACCOUNTED_TIME, 0); 1266 BLKIO_STAT_UNACCOUNTED_TIME, 0, 0);
1143 case BLKIO_PROP_dequeue: 1267 case BLKIO_PROP_dequeue:
1144 return blkio_read_blkg_stats(blkcg, cft, cb, 1268 return blkio_read_blkg_stats(blkcg, cft, cb,
1145 BLKIO_STAT_DEQUEUE, 0); 1269 BLKIO_STAT_DEQUEUE, 0, 0);
1146 case BLKIO_PROP_avg_queue_size: 1270 case BLKIO_PROP_avg_queue_size:
1147 return blkio_read_blkg_stats(blkcg, cft, cb, 1271 return blkio_read_blkg_stats(blkcg, cft, cb,
1148 BLKIO_STAT_AVG_QUEUE_SIZE, 0); 1272 BLKIO_STAT_AVG_QUEUE_SIZE, 0, 0);
1149 case BLKIO_PROP_group_wait_time: 1273 case BLKIO_PROP_group_wait_time:
1150 return blkio_read_blkg_stats(blkcg, cft, cb, 1274 return blkio_read_blkg_stats(blkcg, cft, cb,
1151 BLKIO_STAT_GROUP_WAIT_TIME, 0); 1275 BLKIO_STAT_GROUP_WAIT_TIME, 0, 0);
1152 case BLKIO_PROP_idle_time: 1276 case BLKIO_PROP_idle_time:
1153 return blkio_read_blkg_stats(blkcg, cft, cb, 1277 return blkio_read_blkg_stats(blkcg, cft, cb,
1154 BLKIO_STAT_IDLE_TIME, 0); 1278 BLKIO_STAT_IDLE_TIME, 0, 0);
1155 case BLKIO_PROP_empty_time: 1279 case BLKIO_PROP_empty_time:
1156 return blkio_read_blkg_stats(blkcg, cft, cb, 1280 return blkio_read_blkg_stats(blkcg, cft, cb,
1157 BLKIO_STAT_EMPTY_TIME, 0); 1281 BLKIO_STAT_EMPTY_TIME, 0, 0);
1158#endif 1282#endif
1159 default: 1283 default:
1160 BUG(); 1284 BUG();
@@ -1164,10 +1288,10 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft,
1164 switch(name){ 1288 switch(name){
1165 case BLKIO_THROTL_io_service_bytes: 1289 case BLKIO_THROTL_io_service_bytes:
1166 return blkio_read_blkg_stats(blkcg, cft, cb, 1290 return blkio_read_blkg_stats(blkcg, cft, cb,
1167 BLKIO_STAT_SERVICE_BYTES, 1); 1291 BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1);
1168 case BLKIO_THROTL_io_serviced: 1292 case BLKIO_THROTL_io_serviced:
1169 return blkio_read_blkg_stats(blkcg, cft, cb, 1293 return blkio_read_blkg_stats(blkcg, cft, cb,
1170 BLKIO_STAT_SERVICED, 1); 1294 BLKIO_STAT_CPU_SERVICED, 1, 1);
1171 default: 1295 default:
1172 BUG(); 1296 BUG();
1173 } 1297 }