Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 08 Aug 2006 01:22:37 +0200
From:      Michal Mertl <mime@traveller.cz>
To:        John Baldwin <jhb@freebsd.org>
Cc:        Paul Allen <nospam@ugcs.caltech.edu>, freebsd-current@freebsd.org, Brian Candler <B.Candler@pobox.com>, Peter Jeremy <peterjeremy@optushome.com.au>
Subject:   Re: vmstat's entries type
Message-ID:  <1154992958.2913.26.camel@genius.i.cz>
In-Reply-To: <200607311305.38398.jhb@freebsd.org>
References:  <200607251254.k6PCsBef092737@lurza.secnetix.de> <20060729230214.GI12597@groat.ugcs.caltech.edu> <1154216319.23616.23.camel@genius.i.cz> <200607311305.38398.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-M1f0G+6ZA/CPnYVMw/pL
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

John Baldwin wrote:
> On Saturday 29 July 2006 19:38, Michal Mertl wrote:
> > Paul Allen wrote:
> > > Surely all you need to do is a cheap crit_enter,crit_exit 
> > > while updating the 64-bit per cpu counters.  and on
> > > a 64-bit arch you skip the crit_enter,crit_exit.
> > 
> > Critical_enter/exit seem to be quite lightweight (single
> > read/modify/write of a variable).
> > 
> > > Seriously this is a bike shed.  We can summarize it thus:
> > > statistics should be maintained in 64-bit counters, these
> > > counters should be per-cpu and consistent in that context,
> > > nothing else should appear on the critical path.
> > 
> > Why do you call it a bikesched? I think that your proposal could work
> > but as nobody proposed doing the stuff with critical_* before, the
> > thread may be fruitful. 
> > 
> > Is critical_* good enough protection though? What if two threads were
> > updating the same per-CPU counter on the same CPU at the same time? With
> > 64bits counter on a 32bit architecture? I expect the cache coherency
> > issues are completely eliminated with per-CPU data, aren't they?
> 
> critical_* would prevent an interrupt from preempting the thread, so you 
> wouldn't have this case.
> 
> That said, I think just using a simple algo (like inc; jnc 1b; inc; 1:) would 
> be fine.  With the counter being per-cpu you don't even need the 'lock' 
> prefix for i386.  You would have to find similar solutions for other 32-bit 
> archs (arm, ppc, mips).

Attached please find a diff against fresh CURRENT src/sys, which
basically just wraps all modifications of the vmmeter's counters with
PCPU_CNTR{64,}_INC/ADD. The implementation of the increment is left to
the compiler but it should be easy to write anything MD instead (I
believe compiler generates rather good code (probably very similar to
your sequence above on i386)). The counters were mostly changed to
int64_t; uint should be fine too but I remember BDE said several times
unsigned types are evil :-). The macro may also be changed to give the
user compile-time chance to choose whether to prefer accuracy or speed,
e.g. use critical_enter/exit.

The resulting UP I386 kernel works and the stats seem to look OK. The
consumers have to be changed too (systat needs attached patch, sysctl
needs to be recompiled to catch the change in src/sys/sys/vmmeter.h,
other programs may have to be recompiled/changed a little too).

I would love to measure the performance impact, especially on SMP I386
but I don't have easy access to such a hardware at the moment. I think
the impact shouldn't be measuarable, although the changes in
src/sys/vm_fault/vm_fault(), where atomic_add_int has been replaced by
the simple PCPU increment, may be positive on SMP configs under 
high memory pressure.

Michal

--=-M1f0G+6ZA/CPnYVMw/pL
Content-Disposition: attachment; filename=systat.c.diff
Content-Type: text/x-patch; name=systat.c.diff; charset=ISO-8859-2
Content-Transfer-Encoding: 7bit

Index: vmstat.c
===================================================================
RCS file: /home/fcvs/cvs/src/usr.bin/systat/vmstat.c,v
retrieving revision 1.80
diff -u -r1.80 vmstat.c
--- vmstat.c	1 May 2006 07:02:52 -0000	1.80
+++ vmstat.c	7 Aug 2006 22:43:01 -0000
@@ -74,34 +74,34 @@
 
 static struct Info {
 	long	time[CPUSTATES];
-	u_int v_swtch;		/* context switches */
-	u_int v_trap;		/* calls to trap */
-	u_int v_syscall;	/* calls to syscall() */
-	u_int v_intr;		/* device interrupts */
-	u_int v_soft;		/* software interrupts */
+	int64_t v_swtch;		/* context switches */
+	int64_t v_trap;		/* calls to trap */
+	int64_t v_syscall;	/* calls to syscall() */
+	int64_t v_intr;		/* device interrupts */
+	int64_t v_soft;		/* software interrupts */
 	/*
 	 * Virtual memory activity.
 	 */
-	u_int v_vm_faults;	/* number of address memory faults */
-	u_int v_cow_faults;	/* number of copy-on-writes */
-	u_int v_zfod;		/* pages zero filled on demand */
-	u_int v_ozfod;		/* optimized zero fill pages */
-	u_int v_swapin;		/* swap pager pageins */
-	u_int v_swapout;	/* swap pager pageouts */
-	u_int v_swappgsin;	/* swap pager pages paged in */
-	u_int v_swappgsout;	/* swap pager pages paged out */
-	u_int v_vnodein;	/* vnode pager pageins */
-	u_int v_vnodeout;	/* vnode pager pageouts */
-	u_int v_vnodepgsin;	/* vnode_pager pages paged in */
-	u_int v_vnodepgsout;	/* vnode pager pages paged out */
-	u_int v_intrans;	/* intransit blocking page faults */
-	u_int v_reactivated;	/* number of pages reactivated from free list */
-	u_int v_pdwakeups;	/* number of times daemon has awaken from sleep */
-	u_int v_pdpages;	/* number of pages analyzed by daemon */
-
-	u_int v_dfree;		/* pages freed by daemon */
-	u_int v_pfree;		/* pages freed by exiting processes */
-	u_int v_tfree;		/* total pages freed */
+	int64_t v_vm_faults;	/* number of address memory faults */
+	int64_t v_cow_faults;	/* number of copy-on-writes */
+	int64_t v_zfod;		/* pages zero filled on demand */
+	int64_t v_ozfod;		/* optimized zero fill pages */
+	int64_t v_swapin;		/* swap pager pageins */
+	int64_t v_swapout;	/* swap pager pageouts */
+	int64_t v_swappgsin;	/* swap pager pages paged in */
+	int64_t v_swappgsout;	/* swap pager pages paged out */
+	int64_t v_vnodein;	/* vnode pager pageins */
+	int64_t v_vnodeout;	/* vnode pager pageouts */
+	int64_t v_vnodepgsin;	/* vnode_pager pages paged in */
+	int64_t v_vnodepgsout;	/* vnode pager pages paged out */
+	int64_t v_intrans;	/* intransit blocking page faults */
+	int64_t v_reactivated;	/* number of pages reactivated from free list */
+	int64_t v_pdwakeups;	/* number of times daemon has awaken from sleep */
+	int64_t v_pdpages;	/* number of pages analyzed by daemon */
+
+	int64_t v_dfree;		/* pages freed by daemon */
+	int64_t v_pfree;		/* pages freed by exiting processes */
+	int64_t v_tfree;		/* total pages freed */
 	/*
 	 * Distribution of page usages.
 	 */

--=-M1f0G+6ZA/CPnYVMw/pL
Content-Disposition: attachment; filename=pcpu-counters.diff
Content-Type: text/x-patch; name=pcpu-counters.diff; charset=ISO-8859-2
Content-Transfer-Encoding: 7bit

Index: compat/linprocfs/linprocfs.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/compat/linprocfs/linprocfs.c,v
retrieving revision 1.96
diff -u -r1.96 linprocfs.c
--- compat/linprocfs/linprocfs.c	27 Jun 2006 20:11:58 -0000	1.96
+++ compat/linprocfs/linprocfs.c	7 Aug 2006 17:45:23 -0000
@@ -383,19 +383,25 @@
 		    T2J(cp_time[CP_NICE]) / mp_ncpus,
 		    T2J(cp_time[CP_SYS]) / mp_ncpus,
 		    T2J(cp_time[CP_IDLE]) / mp_ncpus);
+	sumcnt64(&cnt.v_vnodepgsin);
+	sumcnt64(&cnt.v_vnodepgsout);
+	sumcnt64(&cnt.v_swappgsin);
+	sumcnt64(&cnt.v_swappgsout);
+	sumcnt64(&cnt.v_intr);
+	sumcnt64(&cnt.v_swtch);
 	sbuf_printf(sb,
 	    "disk 0 0 0 0\n"
-	    "page %u %u\n"
-	    "swap %u %u\n"
-	    "intr %u\n"
-	    "ctxt %u\n"
+	    "page %jd %jd\n"
+	    "swap %jd %jd\n"
+	    "intr %jd\n"
+	    "ctxt %jd\n"
 	    "btime %lld\n",
-	    cnt.v_vnodepgsin,
-	    cnt.v_vnodepgsout,
-	    cnt.v_swappgsin,
-	    cnt.v_swappgsout,
-	    cnt.v_intr,
-	    cnt.v_swtch,
+	    (intmax_t)cnt.v_vnodepgsin,
+	    (intmax_t)cnt.v_vnodepgsout,
+	    (intmax_t)cnt.v_swappgsin,
+	    (intmax_t)cnt.v_swappgsout,
+	    (intmax_t)cnt.v_intr,
+	    (intmax_t)cnt.v_swtch,
 	    (long long)boottime.tv_sec);
 	return (0);
 }
Index: fs/smbfs/smbfs_io.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/fs/smbfs/smbfs_io.c,v
retrieving revision 1.36
diff -u -r1.36 smbfs_io.c
--- fs/smbfs/smbfs_io.c	25 May 2006 17:16:11 -0000	1.36
+++ fs/smbfs/smbfs_io.c	7 Aug 2006 16:34:38 -0000
@@ -475,8 +475,8 @@
 
 	kva = (vm_offset_t) bp->b_data;
 	pmap_qenter(kva, pages, npages);
-	cnt.v_vnodein++;
-	cnt.v_vnodepgsin += npages;
+	PCPU_CNTR64_INC(cnt.v_vnodein);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsin, npages);
 
 	iov.iov_base = (caddr_t) kva;
 	iov.iov_len = count;
@@ -626,8 +626,8 @@
 
 	kva = (vm_offset_t) bp->b_data;
 	pmap_qenter(kva, pages, npages);
-	cnt.v_vnodeout++;
-	cnt.v_vnodepgsout += count;
+	PCPU_CNTR64_INC(cnt.v_vnodeout);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsout, count);
 
 	iov.iov_base = (caddr_t) kva;
 	iov.iov_len = count;
Index: i386/i386/intr_machdep.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/i386/i386/intr_machdep.c,v
retrieving revision 1.19
diff -u -r1.19 intr_machdep.c
--- i386/i386/intr_machdep.c	12 Jul 2006 21:22:43 -0000	1.19
+++ i386/i386/intr_machdep.c	7 Aug 2006 16:44:07 -0000
@@ -182,7 +182,7 @@
 	 * processed too.
 	 */
 	(*isrc->is_count)++;
-	PCPU_LAZY_INC(cnt.v_intr);
+	PCPU_CNTR64_INC(cnt.v_intr);
 
 	ie = isrc->is_event;
 
Index: kern/kern_fork.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.260
diff -u -r1.260 kern_fork.c
--- kern/kern_fork.c	1 Aug 2006 15:30:56 -0000	1.260
+++ kern/kern_fork.c	7 Aug 2006 17:13:46 -0000
@@ -669,20 +669,20 @@
 	vm_forkproc(td, p2, td2, flags);
 
 	if (flags == (RFFDG | RFPROC)) {
-		atomic_add_int(&cnt.v_forks, 1);
-		atomic_add_int(&cnt.v_forkpages, p2->p_vmspace->vm_dsize +
+		PCPU_CNTR64_INC(cnt.v_forks);
+		PCPU_CNTR64_ADD(cnt.v_forkpages, p2->p_vmspace->vm_dsize +
 		    p2->p_vmspace->vm_ssize);
 	} else if (flags == (RFFDG | RFPROC | RFPPWAIT | RFMEM)) {
-		atomic_add_int(&cnt.v_vforks, 1);
-		atomic_add_int(&cnt.v_vforkpages, p2->p_vmspace->vm_dsize +
+		PCPU_CNTR64_INC(cnt.v_vforks);
+		PCPU_CNTR64_ADD(cnt.v_vforkpages, p2->p_vmspace->vm_dsize +
 		    p2->p_vmspace->vm_ssize);
 	} else if (p1 == &proc0) {
-		atomic_add_int(&cnt.v_kthreads, 1);
-		atomic_add_int(&cnt.v_kthreadpages, p2->p_vmspace->vm_dsize +
+		PCPU_CNTR64_INC(cnt.v_kthreads);
+		PCPU_CNTR64_ADD(cnt.v_kthreadpages, p2->p_vmspace->vm_dsize +
 		    p2->p_vmspace->vm_ssize);
 	} else {
-		atomic_add_int(&cnt.v_rforks, 1);
-		atomic_add_int(&cnt.v_rforkpages, p2->p_vmspace->vm_dsize +
+		PCPU_CNTR64_INC(cnt.v_rforks);
+		PCPU_CNTR64_ADD(cnt.v_rforkpages, p2->p_vmspace->vm_dsize +
 		    p2->p_vmspace->vm_ssize);
 	}
 
Index: kern/kern_synch.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.281
diff -u -r1.281 kern_synch.c
--- kern/kern_synch.c	15 Jun 2006 06:41:57 -0000	1.281
+++ kern/kern_synch.c	7 Aug 2006 16:24:44 -0000
@@ -400,7 +400,7 @@
 	/*
 	 * Finish up stats for outgoing thread.
 	 */
-	cnt.v_swtch++;
+	PCPU_CNTR64_INC(cnt.v_swtch);
 	PCPU_SET(switchtime, new_switchtime);
 	PCPU_SET(switchticks, ticks);
 	CTR4(KTR_PROC, "mi_switch: old thread %p (kse %p, pid %ld, %s)",
Index: kern/kern_thread.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/kern/kern_thread.c,v
retrieving revision 1.234
diff -u -r1.234 kern_thread.c
--- kern/kern_thread.c	30 Jun 2006 08:10:55 -0000	1.234
+++ kern/kern_thread.c	7 Aug 2006 16:25:05 -0000
@@ -509,7 +509,7 @@
 	p->p_rux.rux_iticks += td->td_iticks;
 	PCPU_SET(switchtime, new_switchtime);
 	PCPU_SET(switchticks, ticks);
-	cnt.v_swtch++;
+	PCPU_CNTR64_INC(cnt.v_swtch);
 
 	/* Add our usage into the usage of all our children. */
 	if (p->p_numthreads == 1)
Index: kern/subr_trap.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/kern/subr_trap.c,v
retrieving revision 1.286
diff -u -r1.286 subr_trap.c
--- kern/subr_trap.c	10 Feb 2006 14:59:16 -0000	1.286
+++ kern/subr_trap.c	7 Aug 2006 16:27:17 -0000
@@ -190,7 +190,7 @@
 #endif
 	td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK |
 	    TDF_NEEDRESCHED | TDF_INTERRUPT);
-	cnt.v_soft++;
+	PCPU_CNTR64_INC(cnt.v_soft);
 	mtx_unlock_spin(&sched_lock);
 
 	/*
Index: nfsclient/nfs_bio.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/nfsclient/nfs_bio.c,v
retrieving revision 1.158
diff -u -r1.158 nfs_bio.c
--- nfsclient/nfs_bio.c	25 May 2006 17:16:10 -0000	1.158
+++ nfsclient/nfs_bio.c	7 Aug 2006 17:49:18 -0000
@@ -159,8 +159,8 @@
 
 	kva = (vm_offset_t) bp->b_data;
 	pmap_qenter(kva, pages, npages);
-	cnt.v_vnodein++;
-	cnt.v_vnodepgsin += npages;
+	PCPU_CNTR64_INC(cnt.v_vnodein);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsin, npages);
 
 	iov.iov_base = (caddr_t) kva;
 	iov.iov_len = count;
@@ -323,8 +323,8 @@
 
 	kva = (vm_offset_t) bp->b_data;
 	pmap_qenter(kva, pages, npages);
-	cnt.v_vnodeout++;
-	cnt.v_vnodepgsout += count;
+	PCPU_CNTR64_INC(cnt.v_vnodeout);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsout, count);
 
 	iov.iov_base = (caddr_t) kva;
 	iov.iov_len = count;
Index: sys/pcpu.h
===================================================================
RCS file: /home/fcvs/cvs/src/sys/sys/pcpu.h,v
retrieving revision 1.17
diff -u -r1.17 pcpu.h
--- sys/pcpu.h	7 Feb 2006 21:22:02 -0000	1.17
+++ sys/pcpu.h	7 Aug 2006 15:41:49 -0000
@@ -100,6 +100,14 @@
  *			support single-instruction memory increments.
  */
 #define PCPU_LAZY_INC(var)	(++*PCPU_PTR(var))
+#ifndef PCPU_CNTR_INC
+#define PCPU_CNTR_INC(var)	(++*PCPU_PTR(var))
+#define PCPU_CNTR_ADD(var, dif)	(*PCPU_PTR(var) += dif)
+#endif
+#ifndef PCPU_CNTR64_INC
+#define PCPU_CNTR64_INC(var)	(++*PCPU_PTR(var))
+#define PCPU_CNTR64_ADD(var, dif)	(*PCPU_PTR(var) += dif)
+#endif
 
 /*
  * Machine dependent callouts.  cpu_pcpu_init() is responsible for
Index: sys/vmmeter.h
===================================================================
RCS file: /home/fcvs/cvs/src/sys/sys/vmmeter.h,v
retrieving revision 1.26
diff -u -r1.26 vmmeter.h
--- sys/vmmeter.h	8 Jun 2004 10:37:30 -0000	1.26
+++ sys/vmmeter.h	7 Aug 2006 17:21:01 -0000
@@ -40,35 +40,35 @@
 	/*
 	 * General system activity.
 	 */
-	u_int v_swtch;		/* context switches */
-	u_int v_trap;		/* calls to trap */
-	u_int v_syscall;	/* calls to syscall() */
-	u_int v_intr;		/* device interrupts */
-	u_int v_soft;		/* software interrupts */
+	int64_t v_swtch;		/* context switches */
+	int64_t v_trap;		/* calls to trap */
+	int64_t v_syscall;	/* calls to syscall() */
+	int64_t v_intr;		/* device interrupts */
+	int64_t v_soft;		/* software interrupts */
 	/*
 	 * Virtual memory activity.
 	 */
-	u_int v_vm_faults;	/* number of address memory faults */
-	u_int v_cow_faults;	/* number of copy-on-writes */
-	u_int v_cow_optim;	/* number of optimized copy-on-writes */
-	u_int v_zfod;		/* pages zero filled on demand */
-	u_int v_ozfod;		/* optimized zero fill pages */
-	u_int v_swapin;		/* swap pager pageins */
-	u_int v_swapout;	/* swap pager pageouts */
-	u_int v_swappgsin;	/* swap pager pages paged in */
-	u_int v_swappgsout;	/* swap pager pages paged out */
-	u_int v_vnodein;	/* vnode pager pageins */
-	u_int v_vnodeout;	/* vnode pager pageouts */
-	u_int v_vnodepgsin;	/* vnode_pager pages paged in */
-	u_int v_vnodepgsout;	/* vnode pager pages paged out */
-	u_int v_intrans;	/* intransit blocking page faults */
-	u_int v_reactivated;	/* number of pages reactivated from free list */
-	u_int v_pdwakeups;	/* number of times daemon has awaken from sleep */
-	u_int v_pdpages;	/* number of pages analyzed by daemon */
-
-	u_int v_dfree;		/* pages freed by daemon */
-	u_int v_pfree;		/* pages freed by exiting processes */
-	u_int v_tfree;		/* total pages freed */
+	int64_t v_vm_faults;	/* number of address memory faults */
+	int64_t v_cow_faults;	/* number of copy-on-writes */
+	int64_t v_cow_optim;	/* number of optimized copy-on-writes */
+	int64_t v_zfod;		/* pages zero filled on demand */
+	int64_t v_ozfod;		/* optimized zero fill pages */
+	int64_t v_swapin;		/* swap pager pageins */
+	int64_t v_swapout;	/* swap pager pageouts */
+	int64_t v_swappgsin;	/* swap pager pages paged in */
+	int64_t v_swappgsout;	/* swap pager pages paged out */
+	int64_t v_vnodein;	/* vnode pager pageins */
+	int64_t v_vnodeout;	/* vnode pager pageouts */
+	int64_t v_vnodepgsin;	/* vnode_pager pages paged in */
+	int64_t v_vnodepgsout;	/* vnode pager pages paged out */
+	int64_t v_intrans;	/* intransit blocking page faults */
+	int64_t v_reactivated;	/* number of pages reactivated from free list */
+	int64_t v_pdwakeups;	/* number of times daemon has awaken from sleep */
+	int64_t v_pdpages;	/* number of pages analyzed by daemon */
+
+	int64_t v_dfree;		/* pages freed by daemon */
+	int64_t v_pfree;		/* pages freed by exiting processes */
+	int64_t v_tfree;		/* total pages freed */
 	/*
 	 * Distribution of page usages.
 	 */
@@ -91,14 +91,14 @@
 	/*
 	 * Fork/vfork/rfork activity.
 	 */
-	u_int v_forks;		/* number of fork() calls */
-	u_int v_vforks;		/* number of vfork() calls */
-	u_int v_rforks;		/* number of rfork() calls */
-	u_int v_kthreads;	/* number of fork() calls by kernel */
-	u_int v_forkpages;	/* number of VM pages affected by fork() */
-	u_int v_vforkpages;	/* number of VM pages affected by vfork() */
-	u_int v_rforkpages;	/* number of VM pages affected by rfork() */
-	u_int v_kthreadpages;	/* number of VM pages affected by fork() by kernel */
+	int64_t v_forks;		/* number of fork() calls */
+	int64_t v_vforks;		/* number of vfork() calls */
+	int64_t v_rforks;		/* number of rfork() calls */
+	int64_t v_kthreads;	/* number of fork() calls by kernel */
+	int64_t v_forkpages;	/* number of VM pages affected by fork() */
+	int64_t v_vforkpages;	/* number of VM pages affected by vfork() */
+	int64_t v_rforkpages;	/* number of VM pages affected by rfork() */
+	int64_t v_kthreadpages;	/* number of VM pages affected by fork() by kernel */
 };
 #ifdef _KERNEL
 
@@ -196,15 +196,18 @@
 	int16_t	t_pw;		/* jobs in page wait */
 	int16_t	t_sl;		/* jobs sleeping in core */
 	int16_t	t_sw;		/* swapped out runnable/short block jobs */
-	int32_t	t_vm;		/* total virtual memory */
-	int32_t	t_avm;		/* active virtual memory */
-	int32_t	t_rm;		/* total real memory in use */
-	int32_t	t_arm;		/* active real memory */
-	int32_t	t_vmshr;	/* shared virtual memory */
-	int32_t	t_avmshr;	/* active shared virtual memory */
-	int32_t	t_rmshr;	/* shared real memory */
-	int32_t	t_armshr;	/* active shared real memory */
-	int32_t	t_free;		/* free memory pages */
+	int64_t	t_vm;		/* total virtual memory */
+	int64_t	t_avm;		/* active virtual memory */
+	int64_t	t_rm;		/* total real memory in use */
+	int64_t	t_arm;		/* active real memory */
+	int64_t	t_vmshr;	/* shared virtual memory */
+	int64_t	t_avmshr;	/* active shared virtual memory */
+	int64_t	t_rmshr;	/* shared real memory */
+	int64_t	t_armshr;	/* active shared real memory */
+	int64_t	t_free;		/* free memory pages */
 };
 
+int sumcnt(int *);
+int64_t sumcnt64(int64_t *);
+
 #endif
Index: vm/swap_pager.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/swap_pager.c,v
retrieving revision 1.281
diff -u -r1.281 swap_pager.c
--- vm/swap_pager.c	5 Aug 2006 19:07:07 -0000	1.281
+++ vm/swap_pager.c	7 Aug 2006 15:57:45 -0000
@@ -1068,8 +1068,8 @@
 	vm_page_unlock_queues();
 	bp->b_npages = j - i;
 
-	cnt.v_swapin++;
-	cnt.v_swappgsin += bp->b_npages;
+	PCPU_CNTR64_INC(cnt.v_swapin);
+	PCPU_CNTR64_ADD(cnt.v_swappgsin, bp->b_npages);
 
 	/*
 	 * We still hold the lock on mreq, and our automatic completion routine
@@ -1102,7 +1102,7 @@
 		vm_page_lock_queues();
 		vm_page_flag_set(mreq, PG_WANTED | PG_REFERENCED);
 		vm_page_unlock_queues();
-		cnt.v_intrans++;
+		PCPU_CNTR64_INC(cnt.v_intrans);
 		if (msleep(mreq, VM_OBJECT_MTX(object), PSWP, "swread", hz*20)) {
 			printf(
 "swap_pager: indefinite wait buffer: bufobj: %p, blkno: %jd, size: %ld\n",
@@ -1295,8 +1295,8 @@
 		bp->b_dirtyoff = 0;
 		bp->b_dirtyend = bp->b_bcount;
 
-		cnt.v_swapout++;
-		cnt.v_swappgsout += bp->b_npages;
+		PCPU_CNTR64_INC(cnt.v_swapout);
+		PCPU_CNTR64_ADD(cnt.v_swappgsout, bp->b_npages);
 
 		/*
 		 * asynchronous
Index: vm/vm_fault.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vm_fault.c,v
retrieving revision 1.218
diff -u -r1.218 vm_fault.c
--- vm/vm_fault.c	6 Aug 2006 00:17:17 -0000	1.218
+++ vm/vm_fault.c	7 Aug 2006 15:47:01 -0000
@@ -219,7 +219,7 @@
 
 	hardfault = 0;
 	growstack = TRUE;
-	atomic_add_int(&cnt.v_vm_faults, 1);
+	PCPU_CNTR64_INC(cnt.v_vm_faults);
 
 RetryFault:;
 
@@ -394,7 +394,7 @@
 				}
 				vm_object_pip_wakeup(fs.object);
 				VM_OBJECT_UNLOCK(fs.object);
-				atomic_add_int(&cnt.v_intrans, 1);
+				PCPU_CNTR64_INC(cnt.v_intrans);
 				vm_object_deallocate(fs.first_object);
 				goto RetryFault;
 			}
@@ -667,9 +667,9 @@
 			if ((fs.m->flags & PG_ZERO) == 0) {
 				pmap_zero_page(fs.m);
 			} else {
-				atomic_add_int(&cnt.v_ozfod, 1);
+				PCPU_CNTR64_INC(cnt.v_ozfod);
 			}
-			atomic_add_int(&cnt.v_zfod, 1);
+			PCPU_CNTR64_INC(cnt.v_zfod);
 			fs.m->valid = VM_PAGE_BITS_ALL;
 			break;	/* break to PAGE HAS BEEN FOUND */
 		} else {
@@ -751,7 +751,7 @@
 				vm_page_unlock_queues();
 				fs.first_m = fs.m;
 				fs.m = NULL;
-				atomic_add_int(&cnt.v_cow_optim, 1);
+				PCPU_CNTR64_INC(cnt.v_cow_optim);
 			} else {
 				/*
 				 * Oh, well, lets copy it.
@@ -779,7 +779,7 @@
 			fs.m = fs.first_m;
 			if (!is_first_object_locked)
 				VM_OBJECT_LOCK(fs.object);
-			atomic_add_int(&cnt.v_cow_faults, 1);
+			PCPU_CNTR64_INC(cnt.v_cow_faults);
 		} else {
 			prot &= ~VM_PROT_WRITE;
 		}
Index: vm/vm_meter.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vm_meter.c,v
retrieving revision 1.89
diff -u -r1.89 vm_meter.c
--- vm/vm_meter.c	21 Jul 2006 23:22:49 -0000	1.89
+++ vm/vm_meter.c	7 Aug 2006 17:23:21 -0000
@@ -263,6 +263,60 @@
 	return (SYSCTL_OUT(req, &count, sizeof(int)));
 }
 
+static int
+vcnt64(SYSCTL_HANDLER_ARGS)
+{
+	int64_t count = *(int64_t *)arg1;
+	int offset = (char *)arg1 - (char *)&cnt;
+#ifdef SMP
+	int i;
+
+	for (i = 0; i < mp_ncpus; ++i) {
+		struct pcpu *pcpu = pcpu_find(i);
+		count += *(int64_t *)((char *)&pcpu->pc_cnt + offset);
+	}
+#else
+	count += *(int64_t *)((char *)PCPU_PTR(cnt) + offset);
+#endif
+	return (SYSCTL_OUT(req, &count, sizeof(int64_t)));
+}
+
+int
+sumcnt(int *cntr)
+{
+	int count = *(int *)cntr;
+	int offset = (char *)cntr - (char *)&cnt;
+#ifdef SMP
+	int i;
+
+	for (i = 0; i < mp_ncpus; ++i) {
+		struct pcpu *pcpu = pcpu_find(i);
+		count += *(int *)((char *)&pcpu->pc_cnt + offset);
+	}
+#else
+	count += *(int *)((char *)PCPU_PTR(cnt) + offset);
+#endif
+	return (count);
+}
+
+int64_t
+sumcnt64(int64_t *cntr)
+{
+	int64_t count = *(int64_t *)cntr;
+	int offset = (char *)cntr - (char *)&cnt;
+#ifdef SMP
+	int i;
+
+	for (i = 0; i < mp_ncpus; ++i) {
+		struct pcpu *pcpu = pcpu_find(i);
+		count += *(int64_t *)((char *)&pcpu->pc_cnt + offset);
+	}
+#else
+	count += *(int64_t *)((char *)PCPU_PTR(cnt) + offset);
+#endif
+	return (count);
+}
+
 SYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD,
     0, sizeof(struct vmtotal), vmtotal, "S,vmtotal", 
     "System virtual memory statistics");
@@ -273,56 +327,56 @@
 	"VM meter vm stats");
 SYSCTL_NODE(_vm_stats, OID_AUTO, misc, CTLFLAG_RW, 0, "VM meter misc stats");
 
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_swtch, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_swtch, 0, vcnt, "IU", "Context switches");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_trap, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_trap, 0, vcnt, "IU", "Traps");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_syscall, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_syscall, 0, vcnt, "IU", "Syscalls");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_intr, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_intr, 0, vcnt, "IU", "Hardware interrupts");
-SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_soft, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_soft, 0, vcnt, "IU", "Software interrupts");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vm_faults, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vm_faults, 0, vcnt, "IU", "VM faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_faults, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_cow_faults, 0, vcnt, "IU", "COW faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_optim, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_cow_optim, 0, vcnt, "IU", "Optimized COW faults");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_zfod, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_zfod, 0, vcnt, "IU", "Zero fill");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_ozfod, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_ozfod, 0, vcnt, "IU", "Optimized zero fill");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapin, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_swapin, 0, vcnt, "IU", "Swapin operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapout, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_swapout, 0, vcnt, "IU", "Swapout operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsin, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_swappgsin, 0, vcnt, "IU", "Swapin pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsout, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_swappgsout, 0, vcnt, "IU", "Swapout pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodein, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vnodein, 0, vcnt, "IU", "Vnodein operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodeout, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vnodeout, 0, vcnt, "IU", "Vnodeout operations");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsin, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vnodepgsin, 0, vcnt, "IU", "Vnodein pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsout, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vnodepgsout, 0, vcnt, "IU", "Vnodeout pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_intrans, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_intrans, 0, vcnt, "IU", "In transit page blocking");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_reactivated, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_reactivated, 0, vcnt, "IU", "Reactivated pages");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdwakeups, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_pdwakeups, 0, vcnt, "IU", "Pagedaemon wakeups");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdpages, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_pdpages, 0, vcnt, "IU", "Pagedaemon page scans");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_dfree, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_dfree, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pfree, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_pfree, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tfree, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_tfree, 0, vcnt, "IU", "");
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_swtch, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_swtch, 0, vcnt64, "IU", "Context switches");
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_trap, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_trap, 0, vcnt64, "IU", "Traps");
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_syscall, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_syscall, 0, vcnt64, "IU", "Syscalls");
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_intr, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_intr, 0, vcnt64, "IU", "Hardware interrupts");
+SYSCTL_PROC(_vm_stats_sys, OID_AUTO, v_soft, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_soft, 0, vcnt64, "IU", "Software interrupts");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vm_faults, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vm_faults, 0, vcnt64, "IU", "VM faults");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_faults, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_cow_faults, 0, vcnt64, "IU", "COW faults");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_cow_optim, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_cow_optim, 0, vcnt64, "IU", "Optimized COW faults");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_zfod, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_zfod, 0, vcnt64, "IU", "Zero fill");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_ozfod, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_ozfod, 0, vcnt64, "IU", "Optimized zero fill");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapin, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_swapin, 0, vcnt64, "IU", "Swapin operations");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swapout, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_swapout, 0, vcnt64, "IU", "Swapout operations");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsin, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_swappgsin, 0, vcnt64, "IU", "Swapin pages");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_swappgsout, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_swappgsout, 0, vcnt64, "IU", "Swapout pages");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodein, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vnodein, 0, vcnt64, "IU", "Vnodein operations");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodeout, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vnodeout, 0, vcnt64, "IU", "Vnodeout operations");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsin, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vnodepgsin, 0, vcnt64, "IU", "Vnodein pages");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vnodepgsout, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vnodepgsout, 0, vcnt64, "IU", "Vnodeout pages");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_intrans, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_intrans, 0, vcnt64, "IU", "In transit page blocking");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_reactivated, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_reactivated, 0, vcnt64, "IU", "Reactivated pages");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdwakeups, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_pdwakeups, 0, vcnt64, "IU", "Pagedaemon wakeups");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pdpages, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_pdpages, 0, vcnt64, "IU", "Pagedaemon page scans");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_dfree, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_dfree, 0, vcnt64, "IU", "");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_pfree, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_pfree, 0, vcnt64, "IU", "");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_tfree, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_tfree, 0, vcnt64, "IU", "");
 SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_size, CTLTYPE_UINT|CTLFLAG_RD,
 	&cnt.v_page_size, 0, vcnt, "IU", "");
 SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_page_count, CTLTYPE_UINT|CTLFLAG_RD,
@@ -353,22 +407,22 @@
 	&cnt.v_pageout_free_min, 0, vcnt, "IU", "");
 SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_interrupt_free_min, CTLTYPE_UINT|CTLFLAG_RD,
 	&cnt.v_interrupt_free_min, 0, vcnt, "IU", "");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forks, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_forks, 0, vcnt, "IU", "Number of fork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforks, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vforks, 0, vcnt, "IU", "Number of vfork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforks, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_rforks, 0, vcnt, "IU", "Number of rfork() calls");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreads, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_kthreads, 0, vcnt, "IU", "Number of fork() calls by kernel");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forkpages, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_forkpages, 0, vcnt, "IU", "VM pages affected by fork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforkpages, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_vforkpages, 0, vcnt, "IU", "VM pages affected by vfork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforkpages, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_rforkpages, 0, vcnt, "IU", "VM pages affected by rfork()");
-SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreadpages, CTLTYPE_UINT|CTLFLAG_RD,
-	&cnt.v_kthreadpages, 0, vcnt, "IU", "VM pages affected by fork() by kernel");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forks, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_forks, 0, vcnt64, "IU", "Number of fork() calls");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforks, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vforks, 0, vcnt64, "IU", "Number of vfork() calls");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforks, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_rforks, 0, vcnt64, "IU", "Number of rfork() calls");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreads, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_kthreads, 0, vcnt64, "IU", "Number of fork() calls by kernel");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_forkpages, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_forkpages, 0, vcnt64, "IU", "VM pages affected by fork()");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_vforkpages, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_vforkpages, 0, vcnt64, "IU", "VM pages affected by vfork()");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_rforkpages, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_rforkpages, 0, vcnt64, "IU", "VM pages affected by rfork()");
+SYSCTL_PROC(_vm_stats_vm, OID_AUTO, v_kthreadpages, CTLTYPE_QUAD|CTLFLAG_RD,
+	&cnt.v_kthreadpages, 0, vcnt64, "IU", "VM pages affected by fork() by kernel");
 
 SYSCTL_INT(_vm_stats_misc, OID_AUTO,
 	zero_page_count, CTLFLAG_RD, &vm_page_zero_count, 0, "");
Index: vm/vm_object.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vm_object.c,v
retrieving revision 1.364
diff -u -r1.364 vm_object.c
--- vm/vm_object.c	3 Aug 2006 23:56:11 -0000	1.364
+++ vm/vm_object.c	7 Aug 2006 16:01:57 -0000
@@ -656,7 +656,7 @@
 			"p->busy = %d, p->flags %x\n", p, p->busy, p->flags));
 		if (p->wire_count == 0) {
 			vm_page_free(p);
-			cnt.v_pfree++;
+			PCPU_CNTR64_INC(cnt.v_pfree);
 		} else {
 			vm_page_remove(p);
 		}
Index: vm/vm_page.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vm_page.c,v
retrieving revision 1.321
diff -u -r1.321 vm_page.c
--- vm/vm_page.c	6 Aug 2006 00:15:40 -0000	1.321
+++ vm/vm_page.c	7 Aug 2006 16:03:02 -0000
@@ -1024,7 +1024,7 @@
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	if (VM_PAGE_GETKNOWNQUEUE2(m) != PQ_ACTIVE) {
 		if (VM_PAGE_INQUEUE1(m, PQ_CACHE))
-			cnt.v_reactivated++;
+			PCPU_CNTR64_INC(cnt.v_reactivated);
 		vm_pageq_remove(m);
 		if (m->wire_count == 0 && (m->flags & PG_UNMANAGED) == 0) {
 			if (m->act_count < ACT_INIT)
@@ -1090,7 +1090,7 @@
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	KASSERT(!pmap_page_is_mapped(m),
 	    ("vm_page_free_toq: freeing mapped page %p", m));
-	cnt.v_tfree++;
+	PCPU_CNTR64_INC(cnt.v_tfree);
 
 	if (m->busy || VM_PAGE_INQUEUE1(m, PQ_FREE)) {
 		printf(
@@ -1300,7 +1300,7 @@
 		return;
 	if (m->wire_count == 0 && (m->flags & PG_UNMANAGED) == 0) {
 		if (VM_PAGE_INQUEUE1(m, PQ_CACHE))
-			cnt.v_reactivated++;
+			PCPU_CNTR64_INC(cnt.v_reactivated);
 		vm_page_flag_clear(m, PG_WINATCFLS);
 		vm_pageq_remove(m);
 		if (athead)
Index: vm/vm_pageout.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vm_pageout.c,v
retrieving revision 1.276
diff -u -r1.276 vm_pageout.c
--- vm/vm_pageout.c	1 Aug 2006 19:06:06 -0000	1.276
+++ vm/vm_pageout.c	7 Aug 2006 17:03:25 -0000
@@ -534,7 +534,7 @@
 				goto unlock_return;
 			}
 			next = TAILQ_NEXT(p, listq);
-			cnt.v_pdpages++;
+			PCPU_CNTR64_INC(cnt.v_pdpages);
 			if (p->wire_count != 0 ||
 			    p->hold_count != 0 ||
 			    p->busy != 0 ||
@@ -739,7 +739,7 @@
 	     m != NULL && maxscan-- > 0 && page_shortage > 0;
 	     m = next) {
 
-		cnt.v_pdpages++;
+		PCPU_CNTR64_INC(cnt.v_pdpages);
 
 		if (VM_PAGE_GETQUEUE(m) != PQ_INACTIVE) {
 			goto rescan0;
@@ -850,7 +850,7 @@
 			 * Invalid pages can be easily freed
 			 */
 			vm_page_free(m);
-			cnt.v_dfree++;
+			PCPU_CNTR64_INC(cnt.v_dfree);
 			--page_shortage;
 		} else if (m->dirty == 0) {
 			/*
@@ -1083,7 +1083,7 @@
 		 * The count for pagedaemon pages is done after checking the
 		 * page for eligibility...
 		 */
-		cnt.v_pdpages++;
+		PCPU_CNTR64_INC(cnt.v_pdpages);
 
 		/*
 		 * Check to see "how much" the page has been used.
@@ -1162,7 +1162,7 @@
 				    m));
 				vm_page_free(m);
 				VM_OBJECT_UNLOCK(object);
-				cnt.v_dfree++;
+				PCPU_CNTR64_INC(cnt.v_dfree);
 				cache_last_free = cache_cur;
 				cache_first_failure = -1;
 				break;
@@ -1514,7 +1514,7 @@
 			}
 		}
 		if (vm_pages_needed)
-			cnt.v_pdwakeups++;
+			PCPU_CNTR64_INC(cnt.v_pdwakeups);
 		vm_page_unlock_queues();
 		vm_pageout_scan(pass);
 	}
Index: vm/vnode_pager.c
===================================================================
RCS file: /home/fcvs/cvs/src/sys/vm/vnode_pager.c,v
retrieving revision 1.227
diff -u -r1.227 vnode_pager.c
--- vm/vnode_pager.c	2 Mar 2006 22:13:27 -0000	1.227
+++ vm/vnode_pager.c	7 Aug 2006 17:04:09 -0000
@@ -731,8 +731,8 @@
 			if (i != reqpage)
 				vm_page_free(m[i]);
 		vm_page_unlock_queues();
-		cnt.v_vnodein++;
-		cnt.v_vnodepgsin++;
+		PCPU_CNTR64_INC(cnt.v_vnodein);
+		PCPU_CNTR64_INC(cnt.v_vnodepgsin);
 		error = vnode_pager_input_old(object, m[reqpage]);
 		VM_OBJECT_UNLOCK(object);
 		return (error);
@@ -751,8 +751,8 @@
 				vm_page_free(m[i]);
 		vm_page_unlock_queues();
 		VM_OBJECT_UNLOCK(object);
-		cnt.v_vnodein++;
-		cnt.v_vnodepgsin++;
+		PCPU_CNTR64_INC(cnt.v_vnodein);
+		PCPU_CNTR64_INC(cnt.v_vnodepgsin);
 		return vnode_pager_input_smlfs(object, m[reqpage]);
 	}
 
@@ -885,8 +885,8 @@
 	bp->b_runningbufspace = bp->b_bufsize;
 	atomic_add_int(&runningbufspace, bp->b_runningbufspace);
 
-	cnt.v_vnodein++;
-	cnt.v_vnodepgsin += count;
+	PCPU_CNTR64_INC(cnt.v_vnodein);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsin, count);
 
 	/* do the input */
 	bp->b_iooffset = dbtob(bp->b_blkno);
@@ -1133,8 +1133,8 @@
 	auio.uio_resid = maxsize;
 	auio.uio_td = (struct thread *) 0;
 	error = VOP_WRITE(vp, &auio, ioflags, curthread->td_ucred);
-	cnt.v_vnodeout++;
-	cnt.v_vnodepgsout += ncount;
+	PCPU_CNTR64_INC(cnt.v_vnodeout);
+	PCPU_CNTR64_ADD(cnt.v_vnodepgsout, ncount);
 
 	if (error) {
 		if ((ppscheck = ppsratecheck(&lastfail, &curfail, 1)))

--=-M1f0G+6ZA/CPnYVMw/pL--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1154992958.2913.26.camel>