summaryrefslogtreecommitdiff
path: root/usr.bin/vmstat
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2017-04-17 17:34:47 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2017-04-17 17:34:47 +0000
commit83c9dea1bac40c7c7cbde4ccb3d747134311ab5a (patch)
tree7679e220e254a60031cd36e1421cb9c844a72521 /usr.bin/vmstat
parent21d5d37ba4c0131d6c141695366e266e32cc3bc1 (diff)
downloadsrc-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.c172
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 */