sched_lock && thread_lock()

Attilio Rao attilio at FreeBSD.org
Mon May 21 15:13:08 UTC 2007


Bruce Evans wrote:
> Just change the PCPU_LAZY_INC() macro to access the non-per-cpu global,
> using the same locking as you use for the non-pcpu access method.  I
> do this in some (old) sys trees for the !SMP case.  This gives a small
> unpessimization and fixes reading the values from dead kernels, but
> only in the !SMP case.  I also remove pc_cnt from the pcpu data in the
> !SMP case.  This is a smaller optimization and requires larger changes
> to remove adding up the pcpu data in vm_meter.c.  The adding up can
> be left unchanged since it becomes a no-op if the data is left at all
> zeros.  In the old sys trees, there is no locking for individual accesses,
> so PCPU_LAZY_INC(var) becomes (++(var)).  In the current tree,
> PCPU_LAZY_INC(var) is (++(<pcu var>)) written in asm for some arches to
> ensure that it is atomic with respect to interrupts on these arches.
> Atomicness with respect to interrupts is necessary and sufficient for
> the non-per-cpu global !SMP case too.

So you want these fields to be nomore per-cpu entirely, ok, now I got 
what you mean.

> Bugs found while grepping for sched_locking of VMCNT fields:
> - v_trap is supposed to be updated by PCPU_LAZY_INC(), but subr_trap.c
>   updates it by VMCNT_ADD().  The direct access used to be perfectly 
> unlocked
>   and non-atomic, since it occurs immediately after releasing sched_lock
>   and just used "++".  Now it is atomic and a micro-pessimization.
> - v_trap's name is now hidden by the macro so grepping for it doesn't work.

Great, this is a bug introduced in old code that I didn't catch.
I'm going to switch it to PCPU_LAZY_INC.
Anyways you can grap those in this way (assuming you are in /usr/src/sys/):
$ grep -r trap * | grep VMCNT_

> Non(?)-bugs found while grepping for VMCNT:
> - most updates of v_free_count are via pq->lcnt++ and pq->lcnt-- in
>   vm_page.c and vm_pageq.  pq->lcnt is VMCNT_PTR(&cnt.vm_free_count)
>   for all pq.  The locking for this seems to be correct except of course
>   in sysctls, since it uses vm_page_queue_free_mtx and never needed
>   VMCNT access methods.  The unneeded VMCNT_GET()s for this alone comprise
>   about 1/3 of the VMCNT_GET()s in vm.

You have to consider that VMCNT_*() is used also for dealing with 
'volatilization' of struct vmmeter cnt. it, so, entirely hides all 
implementation details for vmmeter counter. VMCNT_PTR is currently the 
right way to access to these datas if you want to hide the volatile to 
sysctls (and please note that VMCNT_GET() doesn't add any pessimization 
to the current code).

Thanks,
Attilio


More information about the freebsd-arch mailing list