Replace cpu_mb1() and cpu_mb2() with cpu_mfence(), cpu_lfence(), cpu_sfence(),
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 3 Jun 2005 23:57:34 +0000 (23:57 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 3 Jun 2005 23:57:34 +0000 (23:57 +0000)
commit35238fa584e1b78855badc10357c79b8126bcf0f
tree6a1ef2388ab6bcc5771b58b71a1c0a841db814ec
parent0c86998c1d92dd0217fbcc662aebccbc3a648a26
Replace cpu_mb1() and cpu_mb2() with cpu_mfence(), cpu_lfence(), cpu_sfence(),
and cpu_ccfence().  These provide memory and compiler fences to guarentee
read/write ordering of memory and to prevent the compiler itself from
generating reordered code in particular cases.

Most of the cases where care must be taken are tail-chasing FIFO cases,
especially in the IPI messaging code.

At the moment on SMP boxes we use a locked bus cycle on (%%esp) for the
lfence and mfence.  The only other choices are to use a cpuid instruction
or one of the {S,L,M}FENCE instructions.  cpuid is usually horrible, and
the *FENCE instructions do not exist on older cpus.

Linux seems to use the locked bus cycle or *FENCE instruction method.

Although I have no conclusive evidence, a number of crash dumps provided
by David Rhodus has led me to believe that speculative reads by modern cpus,
in particular in HTT situations with Intel cpus, can survive many more
instructions then previously believed.  The only safe solution is to use
an instruction sequence which guarentees proper operation.

I would prefer to avoid the use of a locked bus cycle but at least in the
IPIQ case (the most common case we have to worry about), only one locked
bus cycle is required and then the entire IPIQ can be processed without
further locked cycles.
14 files changed:
sys/cpu/i386/include/cpufunc.h
sys/i386/i386/mp_machdep.c
sys/i386/include/cpufunc.h
sys/kern/kern_clock.c
sys/kern/kern_timeout.c
sys/kern/kern_umtx.c
sys/kern/lwkt_ipiq.c
sys/kern/lwkt_msgport.c
sys/kern/lwkt_thread.c
sys/kern/lwkt_token.c
sys/kern/vfs_jops.c
sys/kern/vfs_journal.c
sys/platform/pc32/i386/mp_machdep.c
sys/sys/thread2.h