linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] block/diskstats: more accurate approximation of io_ticks for slow disks
@ 2020-03-02 10:38 Konstantin Khlebnikov
  2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
  2020-03-02 10:38 ` [PATCH 3/3] block/diskstats: replace time_in_queue with sum of request times Konstantin Khlebnikov
  0 siblings, 2 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2020-03-02 10:38 UTC (permalink / raw)
  To: linux-block, Jens Axboe, linux-kernel; +Cc: Mikulas Patocka, Mike Snitzer

Currently io_ticks is approximated by adding one at each start and end of
requests if jiffies counter has changed. This works perfectly for requests
shorter than a jiffy or if one of requests starts/ends at each jiffy.

If disk executes just one request at a time and they are longer than two
jiffies then only first and last jiffies will be accounted.

Fix is simple: at the end of request add up into io_ticks jiffies passed
since last update rather than just one jiffy.

Example: common HDD executes random read 4k requests around 12ms.

fio --name=test --filename=/dev/sdb --rw=randread --direct=1 --runtime=30 &
iostat -x 10 sdb

Note changes of iostat's "%util" before/after patch:

Before:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdb               0,00     0,00   82,60    0,00   330,40     0,00     8,00     0,96   12,09   12,09    0,00   1,02   8,43

After:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdb               0,00     0,00   82,50    0,00   330,00     0,00     8,00     1,00   12,10   12,10    0,00  12,12  99,99

Fixes: 5b18b5a73760 ("block: delete part_round_stats and switch to less precise counting")
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 block/bio.c           |    8 ++++----
 block/blk-core.c      |    4 ++--
 include/linux/genhd.h |    2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 94d697217887..5319bf8721b7 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1752,14 +1752,14 @@ void bio_check_pages_dirty(struct bio *bio)
 	schedule_work(&bio_dirty_work);
 }
 
-void update_io_ticks(struct hd_struct *part, unsigned long now)
+void update_io_ticks(struct hd_struct *part, unsigned long now, bool end)
 {
 	unsigned long stamp;
 again:
 	stamp = READ_ONCE(part->stamp);
 	if (unlikely(stamp != now)) {
 		if (likely(cmpxchg(&part->stamp, stamp, now) == stamp)) {
-			__part_stat_add(part, io_ticks, 1);
+			__part_stat_add(part, io_ticks, end ? now - stamp : 1);
 		}
 	}
 	if (part->partno) {
@@ -1775,7 +1775,7 @@ void generic_start_io_acct(struct request_queue *q, int op,
 
 	part_stat_lock();
 
-	update_io_ticks(part, jiffies);
+	update_io_ticks(part, jiffies, false);
 	part_stat_inc(part, ios[sgrp]);
 	part_stat_add(part, sectors[sgrp], sectors);
 	part_inc_in_flight(q, part, op_is_write(op));
@@ -1793,7 +1793,7 @@ void generic_end_io_acct(struct request_queue *q, int req_op,
 
 	part_stat_lock();
 
-	update_io_ticks(part, now);
+	update_io_ticks(part, now, true);
 	part_stat_add(part, nsecs[sgrp], jiffies_to_nsecs(duration));
 	part_stat_add(part, time_in_queue, duration);
 	part_dec_in_flight(q, part, op_is_write(req_op));
diff --git a/block/blk-core.c b/block/blk-core.c
index 089e890ab208..caad0dc32333 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1339,7 +1339,7 @@ void blk_account_io_done(struct request *req, u64 now)
 		part_stat_lock();
 		part = req->part;
 
-		update_io_ticks(part, jiffies);
+		update_io_ticks(part, jiffies, true);
 		part_stat_inc(part, ios[sgrp]);
 		part_stat_add(part, nsecs[sgrp], now - req->start_time_ns);
 		part_stat_add(part, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns));
@@ -1381,7 +1381,7 @@ void blk_account_io_start(struct request *rq, bool new_io)
 		rq->part = part;
 	}
 
-	update_io_ticks(part, jiffies);
+	update_io_ticks(part, jiffies, false);
 
 	part_stat_unlock();
 }
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6fbe58538ad6..d5ff7023daa8 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -431,7 +431,7 @@ static inline void free_part_info(struct hd_struct *part)
 	kfree(part->info);
 }
 
-void update_io_ticks(struct hd_struct *part, unsigned long now);
+void update_io_ticks(struct hd_struct *part, unsigned long now, bool end);
 
 /* block/genhd.c */
 extern void device_add_disk(struct device *parent, struct gendisk *disk,


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass
  2020-03-02 10:38 [PATCH 1/3] block/diskstats: more accurate approximation of io_ticks for slow disks Konstantin Khlebnikov
@ 2020-03-02 10:38 ` Konstantin Khlebnikov
  2020-03-02 13:40   ` kbuild test robot
                     ` (2 more replies)
  2020-03-02 10:38 ` [PATCH 3/3] block/diskstats: replace time_in_queue with sum of request times Konstantin Khlebnikov
  1 sibling, 3 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2020-03-02 10:38 UTC (permalink / raw)
  To: linux-block, Jens Axboe, linux-kernel; +Cc: Mikulas Patocka, Mike Snitzer

Reading /proc/diskstats iterates over all cpus for summing each field.
It's faster to sum all fields in one pass.

Hammering /proc/diskstats with fio shows 2x performance improvement:

fio --name=test --numjobs=$JOBS --filename=/proc/diskstats \
    --size=1k --bs=1k --fallocate=none --create_on_open=1 \
    --time_based=1 --runtime=10 --invalidate=0 --group_report

	  JOBS=1	JOBS=10
Before:	  7k iops	64k iops
After:	 18k iops      120k iops

Also this way code is more compact:

add/remove: 1/0 grow/shrink: 0/2 up/down: 194/-1540 (-1346)
Function                                     old     new   delta
part_stat_read_all                             -     194    +194
diskstats_show                              1344     631    -713
part_stat_show                              1219     392    -827
Total: Before=14966947, After=14965601, chg -0.01%

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 block/genhd.c             |   62 +++++++++++++++++++++++++++++++++------------
 block/partition-generic.c |   35 ++++++++++++++-----------
 include/linux/genhd.h     |   10 +++++--
 3 files changed, 72 insertions(+), 35 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index ff6268970ddc..fcc597c243f7 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -46,6 +46,29 @@ static void disk_add_events(struct gendisk *disk);
 static void disk_del_events(struct gendisk *disk);
 static void disk_release_events(struct gendisk *disk);
 
+#ifdef CONFIG_SMP
+void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
+{
+	int cpu;
+
+	memset(stat, 0, sizeof(struct disk_stats));
+	for_each_possible_cpu(cpu) {
+		struct disk_stats *ptr = per_cpu_ptr(part->dkstats, cpu);
+		int group;
+
+		for (group = 0; group < NR_STAT_GROUPS; group++) {
+			stat->nsecs[group] += ptr->nsecs[group];
+			stat->sectors[group] += ptr->sectors[group];
+			stat->ios[group] += ptr->ios[group];
+			stat->merges[group] += ptr->merges[group];
+		}
+
+		stat->io_ticks += ptr->io_ticks;
+		stat->time_in_queue += ptr->time_in_queue;
+	}
+}
+#endif /* CONFIG_SMP */
+
 void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
 {
 	if (queue_is_mq(q))
@@ -1369,6 +1392,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
 	struct hd_struct *hd;
 	char buf[BDEVNAME_SIZE];
 	unsigned int inflight;
+	struct disk_stats stat;
 
 	/*
 	if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next)
@@ -1380,7 +1404,9 @@ static int diskstats_show(struct seq_file *seqf, void *v)
 
 	disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
 	while ((hd = disk_part_iter_next(&piter))) {
+		part_stat_read_all(hd, &stat);
 		inflight = part_in_flight(gp->queue, hd);
+
 		seq_printf(seqf, "%4d %7d %s "
 			   "%lu %lu %lu %u "
 			   "%lu %lu %lu %u "
@@ -1390,23 +1416,27 @@ static int diskstats_show(struct seq_file *seqf, void *v)
 			   "\n",
 			   MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
 			   disk_name(gp, hd->partno, buf),
-			   part_stat_read(hd, ios[STAT_READ]),
-			   part_stat_read(hd, merges[STAT_READ]),
-			   part_stat_read(hd, sectors[STAT_READ]),
-			   (unsigned int)part_stat_read_msecs(hd, STAT_READ),
-			   part_stat_read(hd, ios[STAT_WRITE]),
-			   part_stat_read(hd, merges[STAT_WRITE]),
-			   part_stat_read(hd, sectors[STAT_WRITE]),
-			   (unsigned int)part_stat_read_msecs(hd, STAT_WRITE),
+			   stat.ios[STAT_READ],
+			   stat.merges[STAT_READ],
+			   stat.sectors[STAT_READ],
+			   (unsigned int)div_u64(stat.nsecs[STAT_READ],
+							NSEC_PER_MSEC),
+			   stat.ios[STAT_WRITE],
+			   stat.merges[STAT_WRITE],
+			   stat.sectors[STAT_WRITE],
+			   (unsigned int)div_u64(stat.nsecs[STAT_WRITE],
+							NSEC_PER_MSEC),
 			   inflight,
-			   jiffies_to_msecs(part_stat_read(hd, io_ticks)),
-			   jiffies_to_msecs(part_stat_read(hd, time_in_queue)),
-			   part_stat_read(hd, ios[STAT_DISCARD]),
-			   part_stat_read(hd, merges[STAT_DISCARD]),
-			   part_stat_read(hd, sectors[STAT_DISCARD]),
-			   (unsigned int)part_stat_read_msecs(hd, STAT_DISCARD),
-			   part_stat_read(hd, ios[STAT_FLUSH]),
-			   (unsigned int)part_stat_read_msecs(hd, STAT_FLUSH)
+			   jiffies_to_msecs(stat.io_ticks),
+			   jiffies_to_msecs(stat.time_in_queue),
+			   stat.ios[STAT_DISCARD],
+			   stat.merges[STAT_DISCARD],
+			   stat.sectors[STAT_DISCARD],
+			   (unsigned int)div_u64(stat.nsecs[STAT_DISCARD],
+						 NSEC_PER_MSEC),
+			   stat.ios[STAT_FLUSH],
+			   (unsigned int)div_u64(stat.nsecs[STAT_FLUSH],
+						 NSEC_PER_MSEC)
 			);
 	}
 	disk_part_iter_exit(&piter);
diff --git a/block/partition-generic.c b/block/partition-generic.c
index 564fae77711d..6d3fcb5187cb 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -120,9 +120,12 @@ ssize_t part_stat_show(struct device *dev,
 {
 	struct hd_struct *p = dev_to_part(dev);
 	struct request_queue *q = part_to_disk(p)->queue;
+	struct disk_stats stat;
 	unsigned int inflight;
 
+	part_stat_read_all(p, &stat);
 	inflight = part_in_flight(q, p);
+
 	return sprintf(buf,
 		"%8lu %8lu %8llu %8u "
 		"%8lu %8lu %8llu %8u "
@@ -130,23 +133,23 @@ ssize_t part_stat_show(struct device *dev,
 		"%8lu %8lu %8llu %8u "
 		"%8lu %8u"
 		"\n",
-		part_stat_read(p, ios[STAT_READ]),
-		part_stat_read(p, merges[STAT_READ]),
-		(unsigned long long)part_stat_read(p, sectors[STAT_READ]),
-		(unsigned int)part_stat_read_msecs(p, STAT_READ),
-		part_stat_read(p, ios[STAT_WRITE]),
-		part_stat_read(p, merges[STAT_WRITE]),
-		(unsigned long long)part_stat_read(p, sectors[STAT_WRITE]),
-		(unsigned int)part_stat_read_msecs(p, STAT_WRITE),
+		stat.ios[STAT_READ],
+		stat.merges[STAT_READ],
+		(unsigned long long)stat.sectors[STAT_READ],
+		(unsigned int)div_u64(stat.nsecs[STAT_READ], NSEC_PER_MSEC),
+		stat.ios[STAT_WRITE],
+		stat.merges[STAT_WRITE],
+		(unsigned long long)stat.sectors[STAT_WRITE],
+		(unsigned int)div_u64(stat.nsecs[STAT_WRITE], NSEC_PER_MSEC),
 		inflight,
-		jiffies_to_msecs(part_stat_read(p, io_ticks)),
-		jiffies_to_msecs(part_stat_read(p, time_in_queue)),
-		part_stat_read(p, ios[STAT_DISCARD]),
-		part_stat_read(p, merges[STAT_DISCARD]),
-		(unsigned long long)part_stat_read(p, sectors[STAT_DISCARD]),
-		(unsigned int)part_stat_read_msecs(p, STAT_DISCARD),
-		part_stat_read(p, ios[STAT_FLUSH]),
-		(unsigned int)part_stat_read_msecs(p, STAT_FLUSH));
+		jiffies_to_msecs(stat.io_ticks),
+		jiffies_to_msecs(stat.time_in_queue),
+		stat.ios[STAT_DISCARD],
+		stat.merges[STAT_DISCARD],
+		(unsigned long long)stat.sectors[STAT_DISCARD],
+		(unsigned int)div_u64(stat.nsecs[STAT_DISCARD], NSEC_PER_MSEC),
+		stat.ios[STAT_FLUSH],
+		(unsigned int)div_u64(stat.nsecs[STAT_FLUSH], NSEC_PER_MSEC));
 }
 
 ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index d5ff7023daa8..f1fca2c57092 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -339,6 +339,8 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
 				sizeof(struct disk_stats));
 }
 
+void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat);
+
 static inline int init_part_stats(struct hd_struct *part)
 {
 	part->dkstats = alloc_percpu(struct disk_stats);
@@ -365,6 +367,11 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
 	memset(&part->dkstats, value, sizeof(struct disk_stats));
 }
 
+void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
+{
+	memcpy(stat, &part->dkstats, sizeof(struct disk_stats));
+}
+
 static inline int init_part_stats(struct hd_struct *part)
 {
 	return 1;
@@ -376,9 +383,6 @@ static inline void free_part_stats(struct hd_struct *part)
 
 #endif /* CONFIG_SMP */
 
-#define part_stat_read_msecs(part, which)				\
-	div_u64(part_stat_read(part, nsecs[which]), NSEC_PER_MSEC)
-
 #define part_stat_read_accum(part, field)				\
 	(part_stat_read(part, field[STAT_READ]) +			\
 	 part_stat_read(part, field[STAT_WRITE]) +			\


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] block/diskstats: replace time_in_queue with sum of request times
  2020-03-02 10:38 [PATCH 1/3] block/diskstats: more accurate approximation of io_ticks for slow disks Konstantin Khlebnikov
  2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
@ 2020-03-02 10:38 ` Konstantin Khlebnikov
  1 sibling, 0 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2020-03-02 10:38 UTC (permalink / raw)
  To: linux-block, Jens Axboe, linux-kernel; +Cc: Mikulas Patocka, Mike Snitzer

Column "time_in_queue" in diskstats is supposed to show total waiting time
of all requests. I.e. value should be equal to the sum of times from other
columns. But this is not true, because column "time_in_queue" is counted
separately in jiffies rather than in nanoseconds as other times.

This patch removes redundant counter for "time_in_queue" and shows total
time of read, write, discard and flush requests.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 block/bio.c               |    1 -
 block/blk-core.c          |    1 -
 block/genhd.c             |    7 +++++--
 block/partition-generic.c |    6 +++++-
 include/linux/genhd.h     |    1 -
 5 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 5319bf8721b7..619cde225c60 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1795,7 +1795,6 @@ void generic_end_io_acct(struct request_queue *q, int req_op,
 
 	update_io_ticks(part, now, true);
 	part_stat_add(part, nsecs[sgrp], jiffies_to_nsecs(duration));
-	part_stat_add(part, time_in_queue, duration);
 	part_dec_in_flight(q, part, op_is_write(req_op));
 
 	part_stat_unlock();
diff --git a/block/blk-core.c b/block/blk-core.c
index caad0dc32333..b913626033f7 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1342,7 +1342,6 @@ void blk_account_io_done(struct request *req, u64 now)
 		update_io_ticks(part, jiffies, true);
 		part_stat_inc(part, ios[sgrp]);
 		part_stat_add(part, nsecs[sgrp], now - req->start_time_ns);
-		part_stat_add(part, time_in_queue, nsecs_to_jiffies64(now - req->start_time_ns));
 		part_dec_in_flight(req->q, part, rq_data_dir(req));
 
 		hd_struct_put(part);
diff --git a/block/genhd.c b/block/genhd.c
index fcc597c243f7..ab49ce053a32 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -64,7 +64,6 @@ void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
 		}
 
 		stat->io_ticks += ptr->io_ticks;
-		stat->time_in_queue += ptr->time_in_queue;
 	}
 }
 #endif /* CONFIG_SMP */
@@ -1428,7 +1427,11 @@ static int diskstats_show(struct seq_file *seqf, void *v)
 							NSEC_PER_MSEC),
 			   inflight,
 			   jiffies_to_msecs(stat.io_ticks),
-			   jiffies_to_msecs(stat.time_in_queue),
+			   (unsigned int)div_u64(stat.nsecs[STAT_READ] +
+						 stat.nsecs[STAT_WRITE] +
+						 stat.nsecs[STAT_DISCARD] +
+						 stat.nsecs[STAT_FLUSH],
+							NSEC_PER_MSEC),
 			   stat.ios[STAT_DISCARD],
 			   stat.merges[STAT_DISCARD],
 			   stat.sectors[STAT_DISCARD],
diff --git a/block/partition-generic.c b/block/partition-generic.c
index 6d3fcb5187cb..2a9bc78a116f 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -143,7 +143,11 @@ ssize_t part_stat_show(struct device *dev,
 		(unsigned int)div_u64(stat.nsecs[STAT_WRITE], NSEC_PER_MSEC),
 		inflight,
 		jiffies_to_msecs(stat.io_ticks),
-		jiffies_to_msecs(stat.time_in_queue),
+		(unsigned int)div_u64(stat.nsecs[STAT_READ] +
+				      stat.nsecs[STAT_WRITE] +
+				      stat.nsecs[STAT_DISCARD] +
+				      stat.nsecs[STAT_FLUSH],
+						NSEC_PER_MSEC),
 		stat.ios[STAT_DISCARD],
 		stat.merges[STAT_DISCARD],
 		(unsigned long long)stat.sectors[STAT_DISCARD],
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index f1fca2c57092..e517758adaa4 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -89,7 +89,6 @@ struct disk_stats {
 	unsigned long ios[NR_STAT_GROUPS];
 	unsigned long merges[NR_STAT_GROUPS];
 	unsigned long io_ticks;
-	unsigned long time_in_queue;
 	local_t in_flight[2];
 };
 


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass
  2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
@ 2020-03-02 13:40   ` kbuild test robot
  2020-03-02 13:51   ` Konstantin Khlebnikov
  2020-03-02 14:09   ` kbuild test robot
  2 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2020-03-02 13:40 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: kbuild-all, linux-block@vger.kernel.org, Jens Axboe,
	linux-kernel, Mikulas Patocka, Mike Snitzer

[-- Attachment #1: Type: text/plain, Size: 10558 bytes --]

Hi Konstantin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on block/for-next]
[also build test ERROR on linux/master linus/master v5.6-rc4 next-20200228]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Konstantin-Khlebnikov/block-diskstats-more-accurate-approximation-of-io_ticks-for-slow-disks/20200302-192211
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
config: um-x86_64_defconfig (attached as .config)
compiler: gcc-7 (Debian 7.5.0-5) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=um SUBARCH=x86_64

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: init/do_mounts.o: in function `part_stat_read_all':
>> do_mounts.c:(.text+0x4ef): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: arch/um/kernel/mem.o: in function `part_stat_read_all':
   mem.c:(.text+0x0): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: arch/um/kernel/process.o: in function `part_stat_read_all':
   process.c:(.text+0x25f): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: arch/um/kernel/ptrace.o: in function `part_stat_read_all':
   ptrace.c:(.text+0x14c): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: arch/um/drivers/ubd_kern.o: in function `part_stat_read_all':
   ubd_kern.c:(.text+0x1f41): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/fork.o: in function `part_stat_read_all':
   fork.c:(.text+0xbb2): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/cpu.o: in function `part_stat_read_all':
   cpu.c:(.text+0x6a7): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/exit.o: in function `part_stat_read_all':
   exit.c:(.text+0x5b4): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sysctl.o: in function `part_stat_read_all':
   sysctl.c:(.text+0x18b5): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/signal.o: in function `part_stat_read_all':
   signal.c:(.text+0xcd6): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sys.o: in function `part_stat_read_all':
   sys.c:(.text+0xc36): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/umh.o: in function `part_stat_read_all':
   umh.c:(.text+0xa25): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/task_work.o: in function `part_stat_read_all':
   task_work.c:(.text+0x0): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/reboot.o: in function `part_stat_read_all':
   reboot.c:(.text+0x243): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/kmod.o: in function `part_stat_read_all':
   kmod.c:(.text+0x479): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/core.o: in function `part_stat_read_all':
   core.c:(.text+0xa8e): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/loadavg.o: in function `part_stat_read_all':
   loadavg.c:(.text+0x0): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/clock.o: in function `part_stat_read_all':
   clock.c:(.text+0x24): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/cputime.o: in function `part_stat_read_all':
   cputime.c:(.text+0x4f): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/idle.o: in function `part_stat_read_all':
   idle.c:(.text+0x141): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/fair.o: in function `part_stat_read_all':
   fair.c:(.text+0x125a): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/rt.o: in function `part_stat_read_all':
   rt.c:(.text+0xc24): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/deadline.o: in function `part_stat_read_all':
   deadline.c:(.text+0x11cf): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/wait.o: in function `part_stat_read_all':
   wait.c:(.text+0x7f3): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/wait_bit.o: in function `part_stat_read_all':
   wait_bit.c:(.text+0x215): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/swait.o: in function `part_stat_read_all':
   swait.c:(.text+0x329): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/completion.o: in function `part_stat_read_all':
   completion.c:(.text+0x13a): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/debug.o: in function `part_stat_read_all':
   debug.c:(.text+0xd6e): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/cpuacct.o: in function `part_stat_read_all':
   cpuacct.c:(.text+0x400): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/sched/membarrier.o: in function `part_stat_read_all':
   membarrier.c:(.text+0x8a): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/power/process.o: in function `part_stat_read_all':
   process.c:(.text+0x2cf): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/freezer.o: in function `part_stat_read_all':
   freezer.c:(.text+0x1de): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/time/timer.o: in function `part_stat_read_all':
   timer.c:(.text+0xd7e): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/acct.o: in function `part_stat_read_all':
   acct.c:(.text+0x5e2): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/cgroup/cgroup.o: in function `part_stat_read_all':
   cgroup.c:(.text+0x25e6): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: kernel/seccomp.o: in function `part_stat_read_all':
   seccomp.c:(.text+0x1193): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/filemap.o: in function `part_stat_read_all':
   filemap.c:(.text+0x2826): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/mempool.o: in function `part_stat_read_all':
   mempool.c:(.text+0x741): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/oom_kill.o: in function `part_stat_read_all':
   oom_kill.c:(.text+0x211): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/fadvise.o: in function `part_stat_read_all':
   fadvise.c:(.text+0x27c): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/page-writeback.o: in function `part_stat_read_all':
   page-writeback.c:(.text+0x1cb2): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/readahead.o: in function `part_stat_read_all':
   readahead.c:(.text+0x3c8): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/swap.o: in function `part_stat_read_all':
   swap.c:(.text+0x10de): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/truncate.o: in function `part_stat_read_all':
   truncate.c:(.text+0x6f6): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/vmscan.o: in function `part_stat_read_all':
   vmscan.c:(.text+0x99b): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/shmem.o: in function `part_stat_read_all':
   shmem.c:(.text+0x33ec): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/util.o: in function `part_stat_read_all':
   util.c:(.text+0x8fd): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/vmstat.o: in function `part_stat_read_all':
   vmstat.c:(.text+0x988): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/backing-dev.o: in function `part_stat_read_all':
   backing-dev.c:(.text+0x755): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/slab_common.o: in function `part_stat_read_all':
   slab_common.c:(.text+0x6ff): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here
   ld: mm/compaction.o: in function `part_stat_read_all':
   compaction.c:(.text+0x0): multiple definition of `part_stat_read_all'; init/main.o:main.c:(.text+0x1d5): first defined here

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 8492 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass
  2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
  2020-03-02 13:40   ` kbuild test robot
@ 2020-03-02 13:51   ` Konstantin Khlebnikov
  2020-03-02 14:09   ` kbuild test robot
  2 siblings, 0 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2020-03-02 13:51 UTC (permalink / raw)
  To: linux-block, Jens Axboe, linux-kernel; +Cc: Mikulas Patocka, Mike Snitzer



On 02/03/2020 13.38, Konstantin Khlebnikov wrote:
> Reading /proc/diskstats iterates over all cpus for summing each field.
> It's faster to sum all fields in one pass.
> 
> Hammering /proc/diskstats with fio shows 2x performance improvement:
> 
> fio --name=test --numjobs=$JOBS --filename=/proc/diskstats \
>      --size=1k --bs=1k --fallocate=none --create_on_open=1 \
>      --time_based=1 --runtime=10 --invalidate=0 --group_report
> 
> 	  JOBS=1	JOBS=10
> Before:	  7k iops	64k iops
> After:	 18k iops      120k iops
> 
> Also this way code is more compact:
> 
> add/remove: 1/0 grow/shrink: 0/2 up/down: 194/-1540 (-1346)
> Function                                     old     new   delta
> part_stat_read_all                             -     194    +194
> diskstats_show                              1344     631    -713
> part_stat_show                              1219     392    -827
> Total: Before=14966947, After=14965601, chg -0.01%
> 
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
>   block/genhd.c             |   62 +++++++++++++++++++++++++++++++++------------
>   block/partition-generic.c |   35 ++++++++++++++-----------
>   include/linux/genhd.h     |   10 +++++--
>   3 files changed, 72 insertions(+), 35 deletions(-)
> 
> diff --git a/block/genhd.c b/block/genhd.c
> index ff6268970ddc..fcc597c243f7 100644
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -46,6 +46,29 @@ static void disk_add_events(struct gendisk *disk);
>   static void disk_del_events(struct gendisk *disk);
>   static void disk_release_events(struct gendisk *disk);
>   
> +#ifdef CONFIG_SMP
> +void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)
> +{
> +	int cpu;
> +
> +	memset(stat, 0, sizeof(struct disk_stats));
> +	for_each_possible_cpu(cpu) {
> +		struct disk_stats *ptr = per_cpu_ptr(part->dkstats, cpu);
> +		int group;
> +
> +		for (group = 0; group < NR_STAT_GROUPS; group++) {
> +			stat->nsecs[group] += ptr->nsecs[group];
> +			stat->sectors[group] += ptr->sectors[group];
> +			stat->ios[group] += ptr->ios[group];
> +			stat->merges[group] += ptr->merges[group];
> +		}
> +
> +		stat->io_ticks += ptr->io_ticks;
> +		stat->time_in_queue += ptr->time_in_queue;
> +	}
> +}
> +#endif /* CONFIG_SMP */
> +
>   void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
>   {
>   	if (queue_is_mq(q))
> @@ -1369,6 +1392,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
>   	struct hd_struct *hd;
>   	char buf[BDEVNAME_SIZE];
>   	unsigned int inflight;
> +	struct disk_stats stat;
>   
>   	/*
>   	if (&disk_to_dev(gp)->kobj.entry == block_class.devices.next)
> @@ -1380,7 +1404,9 @@ static int diskstats_show(struct seq_file *seqf, void *v)
>   
>   	disk_part_iter_init(&piter, gp, DISK_PITER_INCL_EMPTY_PART0);
>   	while ((hd = disk_part_iter_next(&piter))) {
> +		part_stat_read_all(hd, &stat);
>   		inflight = part_in_flight(gp->queue, hd);
> +
>   		seq_printf(seqf, "%4d %7d %s "
>   			   "%lu %lu %lu %u "
>   			   "%lu %lu %lu %u "
> @@ -1390,23 +1416,27 @@ static int diskstats_show(struct seq_file *seqf, void *v)
>   			   "\n",
>   			   MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
>   			   disk_name(gp, hd->partno, buf),
> -			   part_stat_read(hd, ios[STAT_READ]),
> -			   part_stat_read(hd, merges[STAT_READ]),
> -			   part_stat_read(hd, sectors[STAT_READ]),
> -			   (unsigned int)part_stat_read_msecs(hd, STAT_READ),
> -			   part_stat_read(hd, ios[STAT_WRITE]),
> -			   part_stat_read(hd, merges[STAT_WRITE]),
> -			   part_stat_read(hd, sectors[STAT_WRITE]),
> -			   (unsigned int)part_stat_read_msecs(hd, STAT_WRITE),
> +			   stat.ios[STAT_READ],
> +			   stat.merges[STAT_READ],
> +			   stat.sectors[STAT_READ],
> +			   (unsigned int)div_u64(stat.nsecs[STAT_READ],
> +							NSEC_PER_MSEC),
> +			   stat.ios[STAT_WRITE],
> +			   stat.merges[STAT_WRITE],
> +			   stat.sectors[STAT_WRITE],
> +			   (unsigned int)div_u64(stat.nsecs[STAT_WRITE],
> +							NSEC_PER_MSEC),
>   			   inflight,
> -			   jiffies_to_msecs(part_stat_read(hd, io_ticks)),
> -			   jiffies_to_msecs(part_stat_read(hd, time_in_queue)),
> -			   part_stat_read(hd, ios[STAT_DISCARD]),
> -			   part_stat_read(hd, merges[STAT_DISCARD]),
> -			   part_stat_read(hd, sectors[STAT_DISCARD]),
> -			   (unsigned int)part_stat_read_msecs(hd, STAT_DISCARD),
> -			   part_stat_read(hd, ios[STAT_FLUSH]),
> -			   (unsigned int)part_stat_read_msecs(hd, STAT_FLUSH)
> +			   jiffies_to_msecs(stat.io_ticks),
> +			   jiffies_to_msecs(stat.time_in_queue),
> +			   stat.ios[STAT_DISCARD],
> +			   stat.merges[STAT_DISCARD],
> +			   stat.sectors[STAT_DISCARD],
> +			   (unsigned int)div_u64(stat.nsecs[STAT_DISCARD],
> +						 NSEC_PER_MSEC),
> +			   stat.ios[STAT_FLUSH],
> +			   (unsigned int)div_u64(stat.nsecs[STAT_FLUSH],
> +						 NSEC_PER_MSEC)
>   			);
>   	}
>   	disk_part_iter_exit(&piter);
> diff --git a/block/partition-generic.c b/block/partition-generic.c
> index 564fae77711d..6d3fcb5187cb 100644
> --- a/block/partition-generic.c
> +++ b/block/partition-generic.c
> @@ -120,9 +120,12 @@ ssize_t part_stat_show(struct device *dev,
>   {
>   	struct hd_struct *p = dev_to_part(dev);
>   	struct request_queue *q = part_to_disk(p)->queue;
> +	struct disk_stats stat;
>   	unsigned int inflight;
>   
> +	part_stat_read_all(p, &stat);
>   	inflight = part_in_flight(q, p);
> +
>   	return sprintf(buf,
>   		"%8lu %8lu %8llu %8u "
>   		"%8lu %8lu %8llu %8u "
> @@ -130,23 +133,23 @@ ssize_t part_stat_show(struct device *dev,
>   		"%8lu %8lu %8llu %8u "
>   		"%8lu %8u"
>   		"\n",
> -		part_stat_read(p, ios[STAT_READ]),
> -		part_stat_read(p, merges[STAT_READ]),
> -		(unsigned long long)part_stat_read(p, sectors[STAT_READ]),
> -		(unsigned int)part_stat_read_msecs(p, STAT_READ),
> -		part_stat_read(p, ios[STAT_WRITE]),
> -		part_stat_read(p, merges[STAT_WRITE]),
> -		(unsigned long long)part_stat_read(p, sectors[STAT_WRITE]),
> -		(unsigned int)part_stat_read_msecs(p, STAT_WRITE),
> +		stat.ios[STAT_READ],
> +		stat.merges[STAT_READ],
> +		(unsigned long long)stat.sectors[STAT_READ],
> +		(unsigned int)div_u64(stat.nsecs[STAT_READ], NSEC_PER_MSEC),
> +		stat.ios[STAT_WRITE],
> +		stat.merges[STAT_WRITE],
> +		(unsigned long long)stat.sectors[STAT_WRITE],
> +		(unsigned int)div_u64(stat.nsecs[STAT_WRITE], NSEC_PER_MSEC),
>   		inflight,
> -		jiffies_to_msecs(part_stat_read(p, io_ticks)),
> -		jiffies_to_msecs(part_stat_read(p, time_in_queue)),
> -		part_stat_read(p, ios[STAT_DISCARD]),
> -		part_stat_read(p, merges[STAT_DISCARD]),
> -		(unsigned long long)part_stat_read(p, sectors[STAT_DISCARD]),
> -		(unsigned int)part_stat_read_msecs(p, STAT_DISCARD),
> -		part_stat_read(p, ios[STAT_FLUSH]),
> -		(unsigned int)part_stat_read_msecs(p, STAT_FLUSH));
> +		jiffies_to_msecs(stat.io_ticks),
> +		jiffies_to_msecs(stat.time_in_queue),
> +		stat.ios[STAT_DISCARD],
> +		stat.merges[STAT_DISCARD],
> +		(unsigned long long)stat.sectors[STAT_DISCARD],
> +		(unsigned int)div_u64(stat.nsecs[STAT_DISCARD], NSEC_PER_MSEC),
> +		stat.ios[STAT_FLUSH],
> +		(unsigned int)div_u64(stat.nsecs[STAT_FLUSH], NSEC_PER_MSEC));
>   }
>   
>   ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr,
> diff --git a/include/linux/genhd.h b/include/linux/genhd.h
> index d5ff7023daa8..f1fca2c57092 100644
> --- a/include/linux/genhd.h
> +++ b/include/linux/genhd.h
> @@ -339,6 +339,8 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
>   				sizeof(struct disk_stats));
>   }
>   
> +void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat);
> +
>   static inline int init_part_stats(struct hd_struct *part)
>   {
>   	part->dkstats = alloc_percpu(struct disk_stats);
> @@ -365,6 +367,11 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
>   	memset(&part->dkstats, value, sizeof(struct disk_stats));
>   }
>   
> +void part_stat_read_all(struct hd_struct *part, struct disk_stats *stat)

^-- forgot "static inline" here

> +{
> +	memcpy(stat, &part->dkstats, sizeof(struct disk_stats));
> +}
> +
>   static inline int init_part_stats(struct hd_struct *part)
>   {
>   	return 1;
> @@ -376,9 +383,6 @@ static inline void free_part_stats(struct hd_struct *part)
>   
>   #endif /* CONFIG_SMP */
>   
> -#define part_stat_read_msecs(part, which)				\
> -	div_u64(part_stat_read(part, nsecs[which]), NSEC_PER_MSEC)
> -
>   #define part_stat_read_accum(part, field)				\
>   	(part_stat_read(part, field[STAT_READ]) +			\
>   	 part_stat_read(part, field[STAT_WRITE]) +			\
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass
  2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
  2020-03-02 13:40   ` kbuild test robot
  2020-03-02 13:51   ` Konstantin Khlebnikov
@ 2020-03-02 14:09   ` kbuild test robot
  2 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2020-03-02 14:09 UTC (permalink / raw)
  To: Konstantin Khlebnikov
  Cc: kbuild-all, linux-block@vger.kernel.org, Jens Axboe,
	linux-kernel, Mikulas Patocka, Mike Snitzer

[-- Attachment #1: Type: text/plain, Size: 1533 bytes --]

Hi Konstantin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on block/for-next]
[also build test ERROR on linux/master linus/master v5.6-rc4 next-20200228]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Konstantin-Khlebnikov/block-diskstats-more-accurate-approximation-of-io_ticks-for-slow-disks/20200302-192211
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
config: nds32-defconfig (attached as .config)
compiler: nds32le-linux-gcc (GCC) 9.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.2.0 make.cross ARCH=nds32 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   nds32le-linux-ld: fs/nfs/flexfilelayout/flexfilelayoutdev.o: in function `part_stat_read_all':
>> flexfilelayoutdev.c:(.text+0x260): multiple definition of `part_stat_read_all'; fs/nfs/flexfilelayout/flexfilelayout.o:flexfilelayout.c:(.text+0x3edc): first defined here

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 10815 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-03-02 14:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-02 10:38 [PATCH 1/3] block/diskstats: more accurate approximation of io_ticks for slow disks Konstantin Khlebnikov
2020-03-02 10:38 ` [PATCH 2/3] block/diskstats: accumulate all per-cpu counters in one pass Konstantin Khlebnikov
2020-03-02 13:40   ` kbuild test robot
2020-03-02 13:51   ` Konstantin Khlebnikov
2020-03-02 14:09   ` kbuild test robot
2020-03-02 10:38 ` [PATCH 3/3] block/diskstats: replace time_in_queue with sum of request times Konstantin Khlebnikov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).