@@ -179,7 +179,8 @@ config BLK_ADDITIONAL_DISKSTAT
bool "Block layer additional diskstat"
default n
help
- Enabling this option adds io latency statistics for each block device.
+ Enabling this option adds io latency and io size statistics for each
+ block device.
If unsure, say N.
@@ -1436,12 +1436,29 @@ static void blk_additional_latency(struct hd_struct *part, const int sgrp,
part_stat_inc(part, latency_table[idx][sgrp]);
}
+
+static void blk_additional_sector(struct hd_struct *part, const int sgrp,
+ unsigned int sectors)
+{
+ unsigned int KB, idx;
+
+ KB = sectors / 2;
+ idx = (KB > 0) ? ilog2(KB) : 0;
+
+ idx = (idx > (ADD_STAT_NUM - 1)) ? (ADD_STAT_NUM - 1) : idx;
+ part_stat_inc(part, size_table[idx][sgrp]);
+}
#else
static void blk_additional_latency(struct hd_struct *part, const int sgrp,
struct request *req, unsigned long start_jiffies)
{
}
+
+static void blk_additional_sector(struct hd_struct *part, const int sgrp,
+ unsigned int sectors)
+{
+}
#endif
static void blk_account_io_completion(struct request *req, unsigned int bytes)
@@ -1452,6 +1469,7 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
part_stat_lock();
part = req->part;
+ blk_additional_sector(part, sgrp, bytes >> SECTOR_SHIFT);
part_stat_add(part, sectors[sgrp], bytes >> 9);
part_stat_unlock();
}
@@ -1506,6 +1524,7 @@ unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors,
update_io_ticks(part, now, false);
part_stat_inc(part, ios[sgrp]);
part_stat_add(part, sectors[sgrp], sectors);
+ blk_additional_sector(part, sgrp, sectors);
part_stat_local_inc(part, in_flight[op_is_write(op)]);
part_stat_unlock();
@@ -1441,6 +1441,26 @@ static ssize_t io_latency_show(struct device *dev, struct device_attribute *attr
static struct device_attribute dev_attr_io_latency =
__ATTR(io_latency, 0444, io_latency_show, NULL);
+
+static ssize_t io_size_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+ size_t count = 0;
+ int i, sgrp;
+
+ for (i = 0; i < ADD_STAT_NUM; i++) {
+ count += scnprintf(buf + count, PAGE_SIZE - count, "%5d KB: ", 1 << i);
+ for (sgrp = 0; sgrp < NR_STAT_GROUPS; sgrp++)
+ count += scnprintf(buf + count, PAGE_SIZE - count, "%lu ",
+ part_stat_read(p, size_table[i][sgrp]));
+ count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+ }
+
+ return count;
+}
+
+static struct device_attribute dev_attr_io_size =
+ __ATTR(io_size, 0444, io_size_show, NULL);
#endif
static struct attribute *disk_attrs[] = {
@@ -1464,6 +1484,7 @@ static struct attribute *disk_attrs[] = {
#endif
#ifdef CONFIG_BLK_ADDITIONAL_DISKSTAT
&dev_attr_io_latency.attr,
+ &dev_attr_io_size.attr,
#endif
NULL
};
@@ -11,10 +11,11 @@ struct disk_stats {
unsigned long merges[NR_STAT_GROUPS];
#ifdef CONFIG_BLK_ADDITIONAL_DISKSTAT
/*
- * We measure latency (ms) for 1, 2, ..., 1024 and >=1024.
+ * We measure latency (ms) and size (sector) for 1, 2, ..., 1024 and >=1024.
*/
#define ADD_STAT_NUM 12
unsigned long latency_table[ADD_STAT_NUM][NR_STAT_GROUPS];
+ unsigned long size_table[ADD_STAT_NUM][NR_STAT_GROUPS];
#endif
unsigned long io_ticks;
local_t in_flight[2];