diff options
author | John Baldwin <jhb@FreeBSD.org> | 2009-10-29 17:34:02 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2009-10-29 17:34:02 +0000 |
commit | f786e2f82e91ee0b3a62cf25a5bc7daf8d2ff109 (patch) | |
tree | b174b861c701f10b06242bde528f4a8609f4f748 /usr.bin/vmstat/vmstat.c | |
parent | 8e43cc231b504e402d008e13679cde85bb1c38a7 (diff) | |
download | src-f786e2f82e91ee0b3a62cf25a5bc7daf8d2ff109.tar.gz src-f786e2f82e91ee0b3a62cf25a5bc7daf8d2ff109.zip |
When fetching sum stats (vmstat -s) from a crash dump, fetch per-CPU counts
and sum them to form the total counts.
PR: bin/135893
Submitted by: Mikolaj Golub to my trociny of gmail
MFC after: 1 week
Notes
Notes:
svn path=/head/; revision=198620
Diffstat (limited to 'usr.bin/vmstat/vmstat.c')
-rw-r--r-- | usr.bin/vmstat/vmstat.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index aa1d13bb47aa..cf4b73a07c26 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include <sys/resource.h> #include <sys/sysctl.h> #include <sys/vmmeter.h> +#include <sys/pcpu.h> #include <vm/vm_param.h> @@ -418,10 +419,90 @@ getuptime(void) } static void +fill_pcpu(struct pcpu ***pcpup, int* maxcpup) +{ + struct pcpu **pcpu; + + int maxcpu, size, i; + + *pcpup = NULL; + + if (kd == NULL) + return; + + maxcpu = kvm_getmaxcpu(kd); + if (maxcpu < 0) + errx(1, "kvm_getmaxcpu: %s", kvm_geterr(kd)); + + pcpu = calloc(maxcpu, sizeof(struct pcpu *)); + if (pcpu == NULL) + err(1, "calloc"); + + for (i = 0; i < maxcpu; i++) { + pcpu[i] = kvm_getpcpu(kd, i); + if (pcpu[i] == (struct pcpu *)-1) + 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) { + 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_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); } else { size_t size = sizeof(unsigned int); #define GET_VM_STATS(cat, name) \ |