From dae897b54db777b48ebe833542bc006f6f73a467 Mon Sep 17 00:00:00 2001 From: Craig Small Date: Sun, 14 Nov 2021 18:50:58 +1100 Subject: [PATCH] vmstat: Use KiB instead of pages for paged in/out While the kernel calls the fields pgpgin and pgpgout, the units here are not pages, but KiB (or 2x 512 sectors). The comments come from the referenced merged request, this commit fixes the "vmstat -s lies" part: https://elixir.bootlin.com/linux/v5.15-rc7/source/block/blk-core.c#L1057 has submit_bio() which includes the count_vm_events(PGPGIN, count) but what is count? it is usually what bio_sectors() returns. bio_sectors() is a macro in https://elixir.bootlin.com/linux/v5.15-rc7/source/include/linux/bio.h#L49 that defines that as bio->bi_iter.bi_size >> 9. 2^9 is 512 or the sector size. So our count is incremented by the number of 512-byte sectors. As @dublio has already pointed out before this result is printed to vmstat, it is /= 2 to give the number of kibibytes (as the sectors were 512 bytes, we now made the block size 2*512 or 1024). The code even has "sectors -> kbytes". So unless there is something very strange going on, pgpgin and pgpgout in /proc/vmstat return kibibytes. What about pages (which is sort of implied in the name) or blocks (as described on the man page)? Pages can vary, but they are generally 4 KiB so they're out. That also means vmstat -s lies :( Blocks are harder to discount. While these too can vary, they can be 1 KiB; they could also be something else (e.g dd its 512, filesystems 4096). However, for memory management inside the kernel, there are sectors and there are (near userland export) KiB, nothing else. It's probably more accurate to say sectors are shifted in and out of block devices and the kernel expresses these transfers to userland as KiB by halving the numbers. What all this means is that using KiB for bi/bo aka pgpgin/pgpgout is more accurate than saying blocks or pages. Signed-off-by: Craig Small References: procps-ng/procps!64 --- vmstat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vmstat.c b/vmstat.c index 4c0bbcfa..3af2b3cc 100644 --- a/vmstat.c +++ b/vmstat.c @@ -890,8 +890,8 @@ static void sum_format(void) printf(_("%13lld stolen cpu ticks\n"), TICv(sstat_STO)); printf(_("%13lld non-nice guest cpu ticks\n"), TICv(sstat_GST)); printf(_("%13lld nice guest cpu ticks\n"), TICv(sstat_GNI)); - printf(_("%13lu pages paged in\n"), VMSTAT_GET(vm_info, VMSTAT_PGPGIN, ul_int)); - printf(_("%13lu pages paged out\n"), VMSTAT_GET(vm_info, VMSTAT_PGPGOUT, ul_int)); + printf(_("%13lu K paged in\n"), VMSTAT_GET(vm_info, VMSTAT_PGPGIN, ul_int)); + printf(_("%13lu K paged out\n"), VMSTAT_GET(vm_info, VMSTAT_PGPGOUT, ul_int)); printf(_("%13lu pages swapped in\n"), VMSTAT_GET(vm_info, VMSTAT_PSWPIN, ul_int)); printf(_("%13lu pages swapped out\n"), VMSTAT_GET(vm_info, VMSTAT_PSWPOUT, ul_int)); printf(_("%13lu interrupts\n"), SYSv(sstat_INT));