bin/135893: 'vmstat -s -M core' is broken
Mikolaj Golub
to.my.trociny at gmail.com
Sun Jun 21 18:40:01 UTC 2009
>Number: 135893
>Category: bin
>Synopsis: 'vmstat -s -M core' is broken
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Jun 21 18:40:00 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Mikolaj Golub
>Release:
>Organization:
>Environment:
FreeBSD fbsd.zhuzha.ua1 8.0-CURRENT FreeBSD 8.0-CURRENT #0 r193993M: Thu Jun 11 17:01:46 EEST 2009 root at zhuzha.ua1:/home/golub/freebsd/build/obj/home/golub/freebsd/src/sys/GENERIC i386
FreeBSD zhuzha.ua1 7.2-STABLE FreeBSD 7.2-STABLE #18: Wed Jun 3 14:28:49 EEST 2009 root at zhuzha.ua1:/usr/obj/usr/src/sys/DEBUG i386
>Description:
'vmstat -s -M core' is broken, printing 0 for most of the counters.
This is because vmstat looks for statistics only in global `cnt' while the values of most of the counters are collected now in per-CPU variables.
>How-To-Repeat:
vmstat -s -M /dev/mem -N /boot/kernel/kernel
and compare with output of
vmstat -s
>Fix:
Attached patch fixes this.
Patch attached with submission follows:
--- usr.bin/vmstat/vmstat.c.orig 2009-02-22 04:11:24.000000000 +0200
+++ usr.bin/vmstat/vmstat.c 2009-06-21 20:51:20.000000000 +0300
@@ -58,6 +58,7 @@
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <sys/pcpu.h>
#include <vm/vm_param.h>
@@ -418,10 +419,93 @@
}
static void
+fill_pcpu(struct pcpu ***p, int* maxcpup) {
+ struct pcpu **pp;
+
+ int maxcpu, size, i;
+
+ *p = NULL;
+
+ if (kd == NULL)
+ return;
+
+ maxcpu = kvm_getmaxcpu(kd);
+ if(maxcpu < 0)
+ errx(1, "kvm_getcptime: %s", kvm_geterr(kd));
+ if(maxcpu == 0) /* XXX: not sure this check makes sence */
+ return;
+
+ size = sizeof(struct pcpu *) * maxcpu;
+ pp = (struct pcpu **)calloc(1, size);
+ if(pp == NULL)
+ err(1, "malloc %zd bytes", size);
+
+ for(i = 0; i < maxcpu; i++) {
+ pp[i] = kvm_getpcpu(kd, i);
+ if(pp[i] == (struct pcpu *)-1)
+ errx(1, "kvm_getpcpu: %s", kvm_geterr(kd));
+ }
+
+ *maxcpup = maxcpu;
+ *p = pp;
+ return;
+}
+
+static void
+free_pcpu(struct pcpu **p, int maxcpu) {
+ int i;
+ for(i = 0; i < maxcpu; i++)
+ free(p[i]);
+ free(p);
+ p = NULL;
+}
+
+static void
fill_vmmeter(struct vmmeter *vmmp)
{
if (kd != NULL) {
+ struct pcpu **ppcpup;
+ int maxcpu, i;
+
kread(X_SUM, vmmp, sizeof(*vmmp));
+
+ fill_pcpu(&ppcpup, &maxcpu);
+ for(i=0; i < maxcpu; i++) {
+ if(ppcpup[i] == NULL)
+ continue;
+#define ADD_FROM_PCPU(i, name) \
+ vmmp->name += ppcpup[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(ppcpup, maxcpu);
} else {
size_t size = sizeof(unsigned int);
#define GET_VM_STATS(cat, name) \
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list