From 018662b54d0325e59616de36351a4caac3484c98 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 25 Jul 2016 16:05:40 -0700 Subject: [PATCH] systat - Refactor memory displays for systat -vm * Report paging and swap activity in bytes and I/Os instead of pages and I/Os (I/Os usually matched pages). * Report zfod and cow in bytes instead of pages. * Replace the REAL and VIRTUAL section with something that makes a bit more sense. Report active memory (this is just active pages), kernel memory (currently just wired but we can add more stuff later), Free (inactive + cache + free is considered free/freeable memory), and total system memory as reported at boot time. Report total RSS - basically how many pages the system is mapping to user processes. Due to sharing this can be a large value. Do not try to report aggregate VSZ as there's no point in doing so any more. Reported swap usage on the main -vm display as well as total swap allocated. * Fix display bug in systat -sw display. * Add "nvme" device type match for the disk display. --- lib/libdevstat/devstat.c | 1 + usr.bin/systat/swap.c | 3 +- usr.bin/systat/vmstat.c | 90 ++++++++++++++++++++++++++++------------ 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/lib/libdevstat/devstat.c b/lib/libdevstat/devstat.c index b8f1f90ffd..5f746b1b1a 100644 --- a/lib/libdevstat/devstat.c +++ b/lib/libdevstat/devstat.c @@ -49,6 +49,7 @@ char devstat_errbuf[DEVSTAT_ERRBUF_SIZE]; */ struct devstat_match_table match_table[] = { {"da", DEVSTAT_TYPE_DIRECT, DEVSTAT_MATCH_TYPE}, + {"nvme", DEVSTAT_TYPE_DIRECT, DEVSTAT_MATCH_TYPE}, {"xa", DEVSTAT_TYPE_DIRECT, DEVSTAT_MATCH_TYPE}, {"cd", DEVSTAT_TYPE_CDROM, DEVSTAT_MATCH_TYPE}, {"scsi", DEVSTAT_TYPE_IF_SCSI, DEVSTAT_MATCH_IF}, diff --git a/usr.bin/systat/swap.c b/usr.bin/systat/swap.c index 61f75bb054..01b1b96156 100644 --- a/usr.bin/systat/swap.c +++ b/usr.bin/systat/swap.c @@ -147,11 +147,10 @@ showswap(void) mvwprintw( wnd, i + 1, - _col, + 0, "%-5s", "Total" ); - _col += 5; } if (kvmsw[i].ksw_total == 0) { mvwprintw( diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c index 232956b668..bd572d01e2 100644 --- a/usr.bin/systat/vmstat.c +++ b/usr.bin/systat/vmstat.c @@ -61,6 +61,8 @@ #include "extern.h" #include "devs.h" +#define NKVMSW 16 + static struct Info { struct kinfo_cputime cp_time; struct vmmeter Vmm; @@ -76,10 +78,13 @@ static struct Info { int inactivevnodes; int activevnodes; long dirtybufspace; + long physmem; + struct kvm_swap kvmsw[NKVMSW]; } s, s1, s2, z; struct kinfo_cputime cp_time, old_cp_time; struct statinfo cur, last, run; +static int kvnsw; #define vmm s.Vmm #define vms s.Vms @@ -158,9 +163,10 @@ static struct nlist namelist[] = { #define STATROW 0 /* uses 1 row and 68 cols */ #define STATCOL 2 #define MEMROW 2 /* uses 4 rows and 31 cols */ -#define MEMCOL 0 +#define MEMCOLA 0 +#define MEMCOLB 20 #define PAGEROW 2 /* uses 4 rows and 26 cols */ -#define PAGECOL 46 +#define PAGECOL 45 #define INTSROW 6 /* uses all rows to bottom and 17 cols */ #define INTSCOL 61 #define PROCSROW 7 /* uses 2 rows and 20 cols */ @@ -307,17 +313,19 @@ labelkre(void) clear(); mvprintw(STATROW, STATCOL + 4, "users Load"); - mvprintw(MEMROW, MEMCOL, "Mem: REAL VIRTUAL"); - mvprintw(MEMROW + 1, MEMCOL, " Tot Share Tot Share"); - mvprintw(MEMROW + 2, MEMCOL, "Act"); - mvprintw(MEMROW + 3, MEMCOL, "All"); + mvprintw(MEMROW + 0, MEMCOLA, "Active "); + mvprintw(MEMROW + 1, MEMCOLA, "Kernel "); + mvprintw(MEMROW + 2, MEMCOLA, "Free "); + mvprintw(MEMROW + 3, MEMCOLA, "Total "); - mvprintw(MEMROW + 1, MEMCOL + 36, "Free"); + mvprintw(MEMROW + 0, MEMCOLB, "VM-rss"); + mvprintw(MEMROW + 1, MEMCOLB, "VM-swp"); + mvprintw(MEMROW + 1, MEMCOLB + 15, "/"); - mvprintw(PAGEROW, PAGECOL, " VN PAGER SWAP PAGER "); - mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); - mvprintw(PAGEROW + 2, PAGECOL, "count"); - mvprintw(PAGEROW + 3, PAGECOL, "pages"); + mvprintw(PAGEROW, PAGECOL, " VN PAGER SWAP PAGER "); + mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); + mvprintw(PAGEROW + 2, PAGECOL, "bytes"); + mvprintw(PAGEROW + 3, PAGECOL, "count"); mvprintw(INTSROW, INTSCOL + 3, " Interrupts"); mvprintw(INTSROW + 1, INTSCOL + 9, "total"); @@ -358,6 +366,7 @@ labelkre(void) mvprintw(DISKROW + 4, DISKCOL, "tpw/s"); mvprintw(DISKROW + 5, DISKCOL, "MBw/s"); mvprintw(DISKROW + 6, DISKCOL, "%% busy"); + /* * For now, we don't support a fourth disk statistic. So there's * no point in providing a label for it. If someone can think of a @@ -414,6 +423,9 @@ labelkre(void) #define PUTRATE(fld, l, c, w) \ Y(fld); \ put64((int64_t)((float)s.fld/etime + 0.5), l, c, w, 'D') +#define PUTRATE_PGTOB(fld, l, c, w) \ + Y(fld); \ + put64((int64_t)((float)s.fld/etime + 0.5) * PAGE_SIZE, l, c, w, 0) #define MAXFAIL 5 #define CPUSTATES 5 @@ -498,14 +510,17 @@ showkre(void) s1.nchpathcount = s.nchpathcount; } +#define LOADCOLS 49 /* Don't but into the 'free' value */ +#define LOADRANGE (100.0 / LOADCOLS) + psiz = 0; f2 = 0.0; for (lc = 0; lc < CPUSTATES; lc++) { uint64_t val = *(uint64_t *)(((uint8_t *)&s.cp_time) + - cpuoffsets[lc]); + cpuoffsets[lc]); f1 = 100.0 * val / total_time; f2 += f1; - l = (int) ((f2 + 1.0) / 2.0) - psiz; + l = (int)((f2 + (LOADRANGE / 2.0)) / LOADRANGE) - psiz; if (f1 > 99.9) f1 = 99.9; /* no room to display 100.0 */ putfloat(f1, GRAPHROW, GRAPHCOL + 10 * lc, 4, 1, 0); @@ -523,6 +538,18 @@ showkre(void) #define pgtokb(pg) (int64_t)((intmax_t)(pg) * vms.v_page_size / 1024) #define pgtomb(pg) (int64_t)((intmax_t)(pg) * vms.v_page_size / (1024 * 1024)) #define pgtob(pg) (int64_t)((intmax_t)(pg) * vms.v_page_size) + + put64(pgtob(vms.v_active_count), MEMROW + 0, MEMCOLA + 7, 6, 0); + put64(pgtob(vms.v_wire_count), MEMROW + 1, MEMCOLA + 7, 6, 0); /*XXX*/ + put64(pgtob(vms.v_inactive_count + + vms.v_cache_count + + vms.v_free_count), MEMROW + 2, MEMCOLA + 7, 6, 0); + put64(s.physmem, MEMROW + 3, MEMCOLA + 7, 6, 0); + put64(pgtob(total.t_rm), MEMROW + 0, MEMCOLB + 7, 6, 0); + put64(pgtob(total.t_vm - total.t_rm), MEMROW + 1, MEMCOLB + 7, 6, 0); + put64(pgtob(s.kvmsw[kvnsw].ksw_total), MEMROW + 1, MEMCOLB + 17, 6, 0); + +#if 0 put64(pgtob(total.t_arm), MEMROW + 2, MEMCOL + 4, 6, 0); put64(pgtob(total.t_armshr), MEMROW + 2, MEMCOL + 11, 6, 0); put64(pgtob(total.t_avm), MEMROW + 2, MEMCOL + 19, 6, 0); @@ -532,15 +559,17 @@ showkre(void) put64(pgtob(total.t_vm), MEMROW + 3, MEMCOL + 19, 6, 0); put64(pgtob(total.t_vmshr), MEMROW + 3, MEMCOL + 26, 6, 0); put64(pgtob(total.t_free), MEMROW + 2, MEMCOL + 34, 6, 0); +#endif + put64(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 0, 4, 'D'); put64(total.t_pw, PROCSROW + 1, PROCSCOL + 4, 4, 'D'); put64(total.t_dw, PROCSROW + 1, PROCSCOL + 8, 4, 'D'); put64(total.t_sl, PROCSROW + 1, PROCSCOL + 12, 4, 'D'); /*put64(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3, 'D');*/ if (extended_vm_stats == 0) { - PUTRATE(Vmm.v_zfod, VMSTATROW + 0, VMSTATCOL, 7); + PUTRATE_PGTOB(Vmm.v_zfod, VMSTATROW + 0, VMSTATCOL, 7); } - PUTRATE(Vmm.v_cow_faults, VMSTATROW + 1, VMSTATCOL, 7); + PUTRATE_PGTOB(Vmm.v_cow_faults, VMSTATROW + 1, VMSTATCOL, 7); put64(pgtob(vms.v_wire_count), VMSTATROW + 2, VMSTATCOL, 7, 0); put64(pgtob(vms.v_active_count), VMSTATROW + 3, VMSTATCOL, 7, 0); put64(pgtob(vms.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 7, 0); @@ -554,8 +583,8 @@ showkre(void) PUTRATE(Vmm.v_intrans, VMSTATROW + 12, VMSTATCOL, 7); if (extended_vm_stats) { - PUTRATE(Vmm.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9); - PUTRATE(Vmm.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9); + PUTRATE_PGTOB(Vmm.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9); + PUTRATE_PGTOB(Vmm.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9); #define nz(x) ((x) ? (x) : 1) put64((s.Vmm.v_zfod - s.Vmm.v_ozfod) * 100 / nz(s.Vmm.v_zfod), VMSTATROW + 13, VMSTATCOL - 16, 9, 'D'); @@ -568,14 +597,14 @@ showkre(void) put64(s.activevnodes, VMSTATROW + 15, VMSTATCOL, 7, 'D'); put64(s.cachedvnodes, VMSTATROW + 16, VMSTATCOL, 7, 'D'); put64(s.inactivevnodes, VMSTATROW + 17, VMSTATCOL, 7, 'D'); - PUTRATE(Vmm.v_vnodein, PAGEROW + 2, PAGECOL + 6, 4); - PUTRATE(Vmm.v_vnodeout, PAGEROW + 2, PAGECOL + 11, 4); - PUTRATE(Vmm.v_swapin, PAGEROW + 2, PAGECOL + 18, 4); - PUTRATE(Vmm.v_swapout, PAGEROW + 2, PAGECOL + 23, 4); - PUTRATE(Vmm.v_vnodepgsin, PAGEROW + 3, PAGECOL + 6, 4); - PUTRATE(Vmm.v_vnodepgsout, PAGEROW + 3, PAGECOL + 11, 4); - PUTRATE(Vmm.v_swappgsin, PAGEROW + 3, PAGECOL + 18, 4); - PUTRATE(Vmm.v_swappgsout, PAGEROW + 3, PAGECOL + 23, 4); + PUTRATE_PGTOB(Vmm.v_vnodepgsin, PAGEROW + 2, PAGECOL + 7, 5); + PUTRATE_PGTOB(Vmm.v_vnodepgsout, PAGEROW + 2, PAGECOL + 13, 5); + PUTRATE_PGTOB(Vmm.v_swappgsin, PAGEROW + 2, PAGECOL + 21, 5); + PUTRATE_PGTOB(Vmm.v_swappgsout, PAGEROW + 2, PAGECOL + 27, 5); + PUTRATE(Vmm.v_vnodein, PAGEROW + 3, PAGECOL + 7, 5); + PUTRATE(Vmm.v_vnodeout, PAGEROW + 3, PAGECOL + 13, 5); + PUTRATE(Vmm.v_swapin, PAGEROW + 3, PAGECOL + 21, 5); + PUTRATE(Vmm.v_swapout, PAGEROW + 3, PAGECOL + 27, 5); PUTRATE(Vmm.v_swtch, GENSTATROW + 1, GENSTATCOL + 1, 4); PUTRATE(Vmm.v_trap, GENSTATROW + 1, GENSTATCOL + 6, 4); PUTRATE(Vmm.v_syscall, GENSTATROW + 1, GENSTATCOL + 11, 4); @@ -730,9 +759,9 @@ put64(intmax_t n, int l, int lc, int w, int type) switch(type) { case 'D': case 0: - type = 'k'; + type = 'K'; break; - case 'k': + case 'K': type = 'M'; break; case 'M': @@ -850,6 +879,9 @@ getinfo(struct Info *ls) size_t vms_size = sizeof(ls->Vms); size_t vmm_size = sizeof(ls->Vmm); size_t nch_size = sizeof(ls->nchstats) * SMP_MAXCPU; + size_t phys_size = sizeof(ls->physmem); + + kvnsw = kvm_getswapinfo(kd, ls->kvmsw, NKVMSW, 0); if (sysctlbyname("vm.vmstats", &ls->Vms, &vms_size, NULL, 0)) { perror("sysctlbyname: vm.vmstats"); @@ -859,6 +891,10 @@ getinfo(struct Info *ls) perror("sysctlbyname: vm.vmstats"); exit(1); } + if (sysctlbyname("hw.physmem", &ls->physmem, &phys_size, NULL, 0)) { + perror("sysctlbyname: hw.physmem"); + exit(1); + } if (kinfo_get_sched_cputime(&ls->cp_time)) err(1, "kinfo_get_sched_cputime"); -- 2.41.0