sched_lock && thread_lock()
Bruce Evans
bde at optusnet.com.au
Tue May 22 10:44:39 UTC 2007
On Tue, 22 May 2007, Bruce Evans wrote:
> I'm still searching for a 1% performance loss in makeworld under UP
> that occurred just after the VMCNT changes. I've only found this
> harmless (?) bug so far:
>
> % Index: vnode_pager.c
> % ===================================================================
> % RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v
> % retrieving revision 1.232
> % retrieving revision 1.233
> % diff -u -2 -r1.232 -r1.233
> % --- vnode_pager.c 14 Oct 2006 23:21:48 -0000 1.232
> % +++ vnode_pager.c 18 May 2007 07:10:50 -0000 1.233
> % @@ -910,6 +910,6 @@
> % atomic_add_int(&runningbufspace, bp->b_runningbufspace);
> % % - cnt.v_vnodein++;
> % - cnt.v_vnodepgsin += count;
> ^^^^^
> % + VMCNT_ADD(vnodein, 1);
> % + VMCNT_ADD(vnodepgsin, 1);
> ^
> % % /* do the input */
4 more translation errors breaking 8 counters altogether (v_vnodepgsin
is broken twice):
% Index: kern_fork.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v
% retrieving revision 1.270
% retrieving revision 1.271
% diff -u -2 -r1.270 -r1.271
% --- kern_fork.c 4 Apr 2007 09:11:32 -0000 1.270
% +++ kern_fork.c 18 May 2007 07:10:45 -0000 1.271
% @@ -666,18 +666,18 @@
%
% if (flags == (RFFDG | RFPROC)) {
% - atomic_add_int(&cnt.v_forks, 1);
% - atomic_add_int(&cnt.v_forkpages, p2->p_vmspace->vm_dsize +
% + VMCNT_ADD(forks, 1);
% + VMCNT_ADD(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 +
^^^^^^^^^^
% + VMCNT_ADD(forks, 1);
^^^^^
% + VMCNT_ADD(forkpages, 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 +
% + VMCNT_ADD(kthreads, 1);
% + VMCNT_ADD(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 +
% + VMCNT_ADD(rforks, 1);
% + VMCNT_ADD(rforkpages, p2->p_vmspace->vm_dsize +
% p2->p_vmspace->vm_ssize);
% }
% Index: vnode_pager.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v
% retrieving revision 1.232
% retrieving revision 1.233
% diff -u -2 -r1.232 -r1.233
% --- vnode_pager.c 14 Oct 2006 23:21:48 -0000 1.232
% +++ vnode_pager.c 18 May 2007 07:10:50 -0000 1.233
% @@ -1158,6 +1159,6 @@
% auio.uio_td = (struct thread *) 0;
% error = VOP_WRITE(vp, &auio, ioflags, curthread->td_ucred);
% - cnt.v_vnodeout++;
^^^
% - cnt.v_vnodepgsout += ncount;
^^^
% + VMCNT_ADD(vnodein, 1);
^^
% + VMCNT_ADD(vnodepgsin, ncount);
^^
%
% if (error) {
> Related API problem: v_vnodein and v_vnodepgsin are not used in the kernel
> except to increment them and to export them using sysctl, so they should
> be incremented using PCPY_LAZY_INC(). However, PCPU_LAZY_INC() can only
> do increments of 1.
Another problem with using PCU_LAZY_INC() is that all counters might need
to be exported to userland by emulators, but only the vm_meter sysctls
understand PCPU_LAZY_INC(). At least the following counters are currently
exported by at least the linprocfs emulator:
v_intr, v_swtch, v_vnodepgsin, v_vnodepgsout
linprocfs accesses all these counters using VMCNT_GET(), but VMCNT_GET()
doesn't work for counters in the pcpu. v_intr is updated by PCPU_LAZY_INC()
so it is broken in linprocfs. The others aren't yet updated by
PCPU_LAZY_INC() so they aren't broken in linprocfs (except the above
bugs break v_vnodepgs*).
Apart from these problems and bugs, PCPU_LAZY_INC() should be used for all
of the counters visible in the above patches.
Bruce
More information about the freebsd-arch
mailing list