]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
block/genhd: use seq_put_decimal_ull for diskstats decimal values
authorDavid Wang <00107082@163.com>
Fri, 8 Nov 2024 05:45:00 +0000 (13:45 +0800)
committerJens Axboe <axboe@kernel.dk>
Wed, 13 Nov 2024 21:02:19 +0000 (14:02 -0700)
seq_printf is costly. For each block device, 19 decimal values are
yielded in /proc/diskstats via seq_printf. On a system with 16 logical
block devices, profiling for open/read/close sequences shows seq_printf
took ~75% samples of diskstats_show:

diskstats_show(92.626% 2269372/2450040)
    seq_printf(76.026% 1725313/2269372)
vsnprintf(99.163% 1710866/1725313)
    format_decode(26.597% 455040/1710866)
    number(19.554% 334542/1710866)
    memcpy_orig(4.183% 71570/1710866)
...
srso_return_thunk(0.009% 148/1725313)
    part_stat_read_all(8.030% 182236/2269372)

One million rounds of open/read/close /proc/diskstats takes:

real 0m37.687s
user 0m0.264s
sys 0m32.911s
On average, each sequence tooks ~0.032ms

With this patch, most decimal values are yield via seq_put_decimal_ull,
performance is significantly improved:

real 0m20.792s
user 0m0.316s
sys 0m20.463s
On average, each sequence tooks ~0.020ms, a ~37.5% improvement.

Signed-off-by: David Wang <00107082@163.com>
Link: https://lore.kernel.org/r/20241108054500.4251-1-00107082@163.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/genhd.c

index 1971c91d6f722eab5cd0bb94b5df12bc3ddb0652..9130e163e1913ad6f3b4e4b0297d49328dea1c57 100644 (file)
@@ -1291,40 +1291,35 @@ static int diskstats_show(struct seq_file *seqf, void *v)
                        part_stat_unlock();
                }
                part_stat_read_all(hd, &stat);
-               seq_printf(seqf, "%4d %7d %pg "
-                          "%lu %lu %lu %u "
-                          "%lu %lu %lu %u "
-                          "%u %u %u "
-                          "%lu %lu %lu %u "
-                          "%lu %u"
-                          "\n",
-                          MAJOR(hd->bd_dev), MINOR(hd->bd_dev), hd,
-                          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(stat.io_ticks),
-                          (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],
-                          (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)
-                       );
+               seq_put_decimal_ull_width(seqf, "",  MAJOR(hd->bd_dev), 4);
+               seq_put_decimal_ull_width(seqf, " ", MINOR(hd->bd_dev), 7);
+               seq_printf(seqf, " %pg", hd);
+               seq_put_decimal_ull(seqf, " ", stat.ios[STAT_READ]);
+               seq_put_decimal_ull(seqf, " ", stat.merges[STAT_READ]);
+               seq_put_decimal_ull(seqf, " ", stat.sectors[STAT_READ]);
+               seq_put_decimal_ull(seqf, " ", (unsigned int)div_u64(stat.nsecs[STAT_READ],
+                                                                    NSEC_PER_MSEC));
+               seq_put_decimal_ull(seqf, " ", stat.ios[STAT_WRITE]);
+               seq_put_decimal_ull(seqf, " ", stat.merges[STAT_WRITE]);
+               seq_put_decimal_ull(seqf, " ", stat.sectors[STAT_WRITE]);
+               seq_put_decimal_ull(seqf, " ", (unsigned int)div_u64(stat.nsecs[STAT_WRITE],
+                                                                    NSEC_PER_MSEC));
+               seq_put_decimal_ull(seqf, " ", inflight);
+               seq_put_decimal_ull(seqf, " ", jiffies_to_msecs(stat.io_ticks));
+               seq_put_decimal_ull(seqf, " ", (unsigned int)div_u64(stat.nsecs[STAT_READ] +
+                                                                    stat.nsecs[STAT_WRITE] +
+                                                                    stat.nsecs[STAT_DISCARD] +
+                                                                    stat.nsecs[STAT_FLUSH],
+                                                                    NSEC_PER_MSEC));
+               seq_put_decimal_ull(seqf, " ", stat.ios[STAT_DISCARD]);
+               seq_put_decimal_ull(seqf, " ", stat.merges[STAT_DISCARD]);
+               seq_put_decimal_ull(seqf, " ", stat.sectors[STAT_DISCARD]);
+               seq_put_decimal_ull(seqf, " ", (unsigned int)div_u64(stat.nsecs[STAT_DISCARD],
+                                                                    NSEC_PER_MSEC));
+               seq_put_decimal_ull(seqf, " ", stat.ios[STAT_FLUSH]);
+               seq_put_decimal_ull(seqf, " ", (unsigned int)div_u64(stat.nsecs[STAT_FLUSH],
+                                                                    NSEC_PER_MSEC));
+               seq_putc(seqf, '\n');
        }
        rcu_read_unlock();