From 48cae112b516ce625d38f22fdc07a29d509de845 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 30 Jul 2015 00:13:20 +0000 Subject: [PATCH] Use private cache line for the locked nop in *mb() on i386. Suggested by: alc Reviewed by: alc, bde Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/i386/i386/vm_machdep.c | 4 +-- sys/i386/include/atomic.h | 71 +++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index f67b279e4393..62e99aa7f2c9 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -111,8 +111,8 @@ _Static_assert(OFFSETOF_CURTHREAD == offsetof(struct pcpu, pc_curthread), "OFFSETOF_CURTHREAD does not correspond with offset of pc_curthread."); _Static_assert(OFFSETOF_CURPCB == offsetof(struct pcpu, pc_curpcb), "OFFSETOF_CURPCB does not correspond with offset of pc_curpcb."); -_Static_assert(OFFSETOF_MONITORBUF == offsetof(struct pcpu, pc_monitorbuf), - "OFFSETOF_MONINORBUF does not correspond with offset of pc_monitorbuf."); +_Static_assert(__OFFSETOF_MONITORBUF == offsetof(struct pcpu, pc_monitorbuf), + "__OFFSETOF_MONINORBUF does not correspond with offset of pc_monitorbuf."); static void cpu_reset_real(void); #ifdef SMP diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index 35919666c35c..15742a51d2a9 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -37,9 +37,31 @@ #include #endif -#define mb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") -#define wmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") -#define rmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") +#ifndef __OFFSETOF_MONITORBUF +/* + * __OFFSETOF_MONITORBUF == __pcpu_offset(pc_monitorbuf). + * + * The open-coded number is used instead of the symbolic expression to + * avoid a dependency on sys/pcpu.h in machine/atomic.h consumers. + * An assertion in i386/vm_machdep.c ensures that the value is correct. + */ +#define __OFFSETOF_MONITORBUF 0x180 + +static __inline void +__mbk(void) +{ + + __asm __volatile("lock; addl $0,%%fs:%0" + : "+m" (*(u_int *)__OFFSETOF_MONITORBUF) : : "memory", "cc"); +} + +static __inline void +__mbu(void) +{ + + __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc"); +} +#endif /* * Various simple operations on memory, each of which is atomic in the @@ -246,40 +268,15 @@ atomic_testandset_int(volatile u_int *p, u_int v) * reordering accesses in a way that violates the semantics of acquire * and release. */ + #if defined(_KERNEL) - -/* - * OFFSETOF_MONITORBUF == __pcpu_offset(pc_monitorbuf). - * - * The open-coded number is used instead of the symbolic expression to - * avoid a dependency on sys/pcpu.h in machine/atomic.h consumers. - * An assertion in i386/vm_machdep.c ensures that the value is correct. - */ -#define OFFSETOF_MONITORBUF 0x180 - #if defined(SMP) -static __inline void -__storeload_barrier(void) -{ - - __asm __volatile("lock; addl $0,%%fs:%0" - : "+m" (*(u_int *)OFFSETOF_MONITORBUF) : : "memory", "cc"); -} +#define __storeload_barrier() __mbk() #else /* _KERNEL && UP */ -static __inline void -__storeload_barrier(void) -{ - - __compiler_membar(); -} +#define __storeload_barrier() __compiler_membar() #endif /* SMP */ #else /* !_KERNEL */ -static __inline void -__storeload_barrier(void) -{ - - __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc"); -} +#define __storeload_barrier() __mbu() #endif /* _KERNEL*/ #define ATOMIC_LOAD(TYPE) \ @@ -776,4 +773,14 @@ u_long atomic_swap_long(volatile u_long *p, u_long v); #endif /* !WANT_FUNCTIONS */ +#if defined(_KERNEL) +#define mb() __mbk() +#define wmb() __mbk() +#define rmb() __mbk() +#else +#define mb() __mbu() +#define wmb() __mbu() +#define rmb() __mbu() +#endif + #endif /* !_MACHINE_ATOMIC_H_ */