diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2017-04-17 17:34:47 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2017-04-17 17:34:47 +0000 |
commit | 83c9dea1bac40c7c7cbde4ccb3d747134311ab5a (patch) | |
tree | 7679e220e254a60031cd36e1421cb9c844a72521 /usr.bin/vmstat | |
parent | 21d5d37ba4c0131d6c141695366e266e32cc3bc1 (diff) | |
download | src-test2-83c9dea1bac40c7c7cbde4ccb3d747134311ab5a.tar.gz src-test2-83c9dea1bac40c7c7cbde4ccb3d747134311ab5a.zip |
- Remove 'struct vmmeter' from 'struct pcpu', leaving only global vmmeter
in place. To do per-cpu stats, convert all fields that previously were
maintained in the vmmeters that sit in pcpus to counter(9).
- Since some vmmeter stats may be touched at very early stages of boot,
before we have set up UMA and we can do counter_u64_alloc(), provide an
early counter mechanism:
o Leave one spare uint64_t in struct pcpu, named pc_early_dummy_counter.
o Point counter(9) fields of vmmeter to pcpu[0].pc_early_dummy_counter,
so that at early stages of boot, before counters are allocated we already
point to a counter that can be safely written to.
o For sparc64 that required a whole dummy pcpu[MAXCPU] array.
Further related changes:
- Don't include vmmeter.h into pcpu.h.
- vm.stats.vm.v_swappgsout and vm.stats.vm.v_swappgsin changed to 64-bit,
to match kernel representation.
- struct vmmeter hidden under _KERNEL, and only vmstat(1) is an exclusion.
This is based on benno@'s 4-year old patch:
https://lists.freebsd.org/pipermail/freebsd-arch/2013-July/014471.html
Reviewed by: kib, gallatin, marius, lidl
Differential Revision: https://reviews.freebsd.org/D10156
Notes
Notes:
svn path=/head/; revision=317061
Diffstat (limited to 'usr.bin/vmstat')
-rw-r--r-- | usr.bin/vmstat/vmstat.c | 172 |
1 files changed, 90 insertions, 82 deletions
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index bc734f045a12..58e96b6f33b5 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/time.h> #include <sys/user.h> +#define _WANT_VMMETER #include <sys/vmmeter.h> #include <sys/pcpu.h> @@ -127,7 +128,57 @@ static long select_generation; static char **specified_devices; static devstat_select_mode select_mode; -static struct vmmeter sum, osum; +static struct __vmmeter { + uint64_t v_swtch; + uint64_t v_trap; + uint64_t v_syscall; + uint64_t v_intr; + uint64_t v_soft; + uint64_t v_vm_faults; + uint64_t v_io_faults; + uint64_t v_cow_faults; + uint64_t v_cow_optim; + uint64_t v_zfod; + uint64_t v_ozfod; + uint64_t v_swapin; + uint64_t v_swapout; + uint64_t v_swappgsin; + uint64_t v_swappgsout; + uint64_t v_vnodein; + uint64_t v_vnodeout; + uint64_t v_vnodepgsin; + uint64_t v_vnodepgsout; + uint64_t v_intrans; + uint64_t v_reactivated; + uint64_t v_pdwakeups; + uint64_t v_pdpages; + uint64_t v_pdshortfalls; + uint64_t v_dfree; + uint64_t v_pfree; + uint64_t v_tfree; + uint64_t v_forks; + uint64_t v_vforks; + uint64_t v_rforks; + uint64_t v_kthreads; + uint64_t v_forkpages; + uint64_t v_vforkpages; + uint64_t v_rforkpages; + uint64_t v_kthreadpages; + u_int v_page_size; + u_int v_page_count; + u_int v_free_reserved; + u_int v_free_target; + u_int v_free_min; + u_int v_free_count; + u_int v_wire_count; + u_int v_active_count; + u_int v_inactive_target; + u_int v_inactive_count; + u_int v_laundry_count; + u_int v_pageout_free_min; + u_int v_interrupt_free_min; + u_int v_free_severe; +} sum, osum; #define VMSTAT_DEFAULT_LINES 20 /* Default number of `winlines'. */ volatile sig_atomic_t wresized; /* Tty resized, when non-zero. */ @@ -448,93 +499,50 @@ getuptime(void) } static void -fill_pcpu(struct pcpu ***pcpup, int* maxcpup) -{ - struct pcpu **pcpu; - - int maxcpu, i; - - *pcpup = NULL; - - if (kd == NULL) - return; - - maxcpu = kvm_getmaxcpu(kd); - if (maxcpu < 0) - xo_errx(1, "kvm_getmaxcpu: %s", kvm_geterr(kd)); - - pcpu = calloc(maxcpu, sizeof(struct pcpu *)); - if (pcpu == NULL) - xo_err(1, "calloc"); - - for (i = 0; i < maxcpu; i++) { - pcpu[i] = kvm_getpcpu(kd, i); - if (pcpu[i] == (struct pcpu *)-1) - xo_errx(1, "kvm_getpcpu: %s", kvm_geterr(kd)); - } - - *maxcpup = maxcpu; - *pcpup = pcpu; -} - -static void -free_pcpu(struct pcpu **pcpu, int maxcpu) -{ - int i; - - for (i = 0; i < maxcpu; i++) - free(pcpu[i]); - free(pcpu); -} - -static void -fill_vmmeter(struct vmmeter *vmmp) +fill_vmmeter(struct __vmmeter *vmmp) { struct pcpu **pcpu; int maxcpu, i; if (kd != NULL) { - kread(X_SUM, vmmp, sizeof(*vmmp)); - fill_pcpu(&pcpu, &maxcpu); - for (i = 0; i < maxcpu; i++) { - if (pcpu[i] == NULL) - continue; -#define ADD_FROM_PCPU(i, name) \ - vmmp->name += pcpu[i]->pc_cnt.name - ADD_FROM_PCPU(i, v_swtch); - ADD_FROM_PCPU(i, v_trap); - ADD_FROM_PCPU(i, v_syscall); - ADD_FROM_PCPU(i, v_intr); - ADD_FROM_PCPU(i, v_soft); - ADD_FROM_PCPU(i, v_vm_faults); - ADD_FROM_PCPU(i, v_io_faults); - ADD_FROM_PCPU(i, v_cow_faults); - ADD_FROM_PCPU(i, v_cow_optim); - ADD_FROM_PCPU(i, v_zfod); - ADD_FROM_PCPU(i, v_ozfod); - ADD_FROM_PCPU(i, v_swapin); - ADD_FROM_PCPU(i, v_swapout); - ADD_FROM_PCPU(i, v_swappgsin); - ADD_FROM_PCPU(i, v_swappgsout); - ADD_FROM_PCPU(i, v_vnodein); - ADD_FROM_PCPU(i, v_vnodeout); - ADD_FROM_PCPU(i, v_vnodepgsin); - ADD_FROM_PCPU(i, v_vnodepgsout); - ADD_FROM_PCPU(i, v_intrans); - ADD_FROM_PCPU(i, v_tfree); - ADD_FROM_PCPU(i, v_forks); - ADD_FROM_PCPU(i, v_vforks); - ADD_FROM_PCPU(i, v_rforks); - ADD_FROM_PCPU(i, v_kthreads); - ADD_FROM_PCPU(i, v_forkpages); - ADD_FROM_PCPU(i, v_vforkpages); - ADD_FROM_PCPU(i, v_rforkpages); - ADD_FROM_PCPU(i, v_kthreadpages); -#undef ADD_FROM_PCPU - } - free_pcpu(pcpu, maxcpu); + struct vmmeter vm_cnt; + + kread(X_SUM, &vm_cnt, sizeof(vm_cnt)); +#define GET_COUNTER(name) \ + vmmp->name = kvm_counter_u64_fetch(kd, (u_long)vm_cnt.name) + GET_COUNTER(v_swtch); + GET_COUNTER(v_trap); + GET_COUNTER(v_syscall); + GET_COUNTER(v_intr); + GET_COUNTER(v_soft); + GET_COUNTER(v_vm_faults); + GET_COUNTER(v_io_faults); + GET_COUNTER(v_cow_faults); + GET_COUNTER(v_cow_optim); + GET_COUNTER(v_zfod); + GET_COUNTER(v_ozfod); + GET_COUNTER(v_swapin); + GET_COUNTER(v_swapout); + GET_COUNTER(v_swappgsin); + GET_COUNTER(v_swappgsout); + GET_COUNTER(v_vnodein); + GET_COUNTER(v_vnodeout); + GET_COUNTER(v_vnodepgsin); + GET_COUNTER(v_vnodepgsout); + GET_COUNTER(v_intrans); + GET_COUNTER(v_tfree); + GET_COUNTER(v_forks); + GET_COUNTER(v_vforks); + GET_COUNTER(v_rforks); + GET_COUNTER(v_kthreads); + GET_COUNTER(v_forkpages); + GET_COUNTER(v_vforkpages); + GET_COUNTER(v_rforkpages); + GET_COUNTER(v_kthreadpages); +#undef GET_COUNTER } else { - size_t size = sizeof(unsigned int); + size_t size = sizeof(uint64_t); + #define GET_VM_STATS(cat, name) \ mysysctl("vm.stats." #cat "." #name, &vmmp->name, &size, NULL, 0) /* sys */ |