Date: Sun, 21 Jun 2009 18:39:27 GMT From: Mikolaj Golub <to.my.trociny@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/135893: 'vmstat -s -M core' is broken Message-ID: <200906211839.n5LIdR5W020047@www.freebsd.org> Resent-Message-ID: <200906211840.n5LIe1fX015276@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906211839.n5LIdR5W020047>