summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2012-07-24 22:10:11 +0000
committerjimharris <jimharris@FreeBSD.org>2012-07-24 22:10:11 +0000
commit5678725c107931060451c983705497c473ae3ba6 (patch)
treedf4ad7e7f670cb7b384865ba22f479d6714769f2 /sys/x86
parent9d1f67b42132c88af75b8ad922c256227cef5960 (diff)
downloadFreeBSD-src-5678725c107931060451c983705497c473ae3ba6.zip
FreeBSD-src-5678725c107931060451c983705497c473ae3ba6.tar.gz
Add rmb() to tsc_read_##x to enforce serialization of rdtsc captures.
Intel Architecture Manual specifies that rdtsc instruction is not serialized, so without this change, TSC synchronization test would periodically fail, resulting in use of HPET timecounter instead of TSC-low. This caused severe performance degradation (40-50%) when running high IO/s workloads due to HPET MMIO reads and GEOM stat collection. Tests on Xeon E5-2600 (Sandy Bridge) 8C systems were seeing TSC synchronization fail approximately 20% of the time. Sponsored by: Intel Reviewed by: kib MFC after: 3 days
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/x86/tsc.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
index 085c339..c253a96 100644
--- a/sys/x86/x86/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -328,6 +328,7 @@ init_TSC(void)
#ifdef SMP
+/* rmb is required here because rdtsc is not a serializing instruction. */
#define TSC_READ(x) \
static void \
tsc_read_##x(void *arg) \
@@ -335,6 +336,7 @@ tsc_read_##x(void *arg) \
uint32_t *tsc = arg; \
u_int cpu = PCPU_GET(cpuid); \
\
+ rmb(); \
tsc[cpu * 3 + x] = rdtsc32(); \
}
TSC_READ(0)
OpenPOWER on IntegriCloud