summaryrefslogtreecommitdiffstats
path: root/usr.bin/vmstat
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-10-29 17:34:02 +0000
committerjhb <jhb@FreeBSD.org>2009-10-29 17:34:02 +0000
commit2f0c1c2a24e28ff242924df262c16fa4dd7a238d (patch)
treeb174b861c701f10b06242bde528f4a8609f4f748 /usr.bin/vmstat
parent204692cbe54f32a27ff98cccb006d0269ba99290 (diff)
downloadFreeBSD-src-2f0c1c2a24e28ff242924df262c16fa4dd7a238d.zip
FreeBSD-src-2f0c1c2a24e28ff242924df262c16fa4dd7a238d.tar.gz
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
Diffstat (limited to 'usr.bin/vmstat')
-rw-r--r--usr.bin/vmstat/vmstat.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c
index aa1d13b..cf4b73a 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) \
OpenPOWER on IntegriCloud