svn commit: r344157 - stable/12/lib/libc/x86/sys
Konstantin Belousov
kib at FreeBSD.org
Fri Feb 15 11:33:49 UTC 2019
Author: kib
Date: Fri Feb 15 11:33:48 2019
New Revision: 344157
URL: https://svnweb.freebsd.org/changeset/base/344157
Log:
MFC r343855, r343859:
Use ifunc to select the barrier instruction for RDTSC.
Modified:
stable/12/lib/libc/x86/sys/__vdso_gettc.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/lib/libc/x86/sys/__vdso_gettc.c
==============================================================================
--- stable/12/lib/libc/x86/sys/__vdso_gettc.c Fri Feb 15 11:28:32 2019 (r344156)
+++ stable/12/lib/libc/x86/sys/__vdso_gettc.c Fri Feb 15 11:33:48 2019 (r344157)
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012 Konstantin Belousov <kib at FreeBSD.org>
- * Copyright (c) 2016, 2017 The FreeBSD Foundation
+ * Copyright (c) 2016, 2017, 2019 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Konstantin Belousov
@@ -50,15 +50,9 @@ __FBSDID("$FreeBSD$");
#ifdef WANT_HYPERV
#include <dev/hyperv/hyperv.h>
#endif
+#include <x86/ifunc.h>
#include "libc_private.h"
-static enum LMB {
- LMB_UNKNOWN,
- LMB_NONE,
- LMB_MFENCE,
- LMB_LFENCE
-} lfence_works = LMB_UNKNOWN;
-
static void
cpuidp(u_int leaf, u_int p[4])
{
@@ -84,68 +78,36 @@ cpuidp(u_int leaf, u_int p[4])
: "0" (leaf));
}
-static enum LMB
-select_lmb(void)
+static void
+rdtsc_mb_lfence(void)
{
- u_int p[4];
- static const char intel_id[] = "GenuntelineI";
- cpuidp(0, p);
- return (memcmp(p + 1, intel_id, sizeof(intel_id) - 1) == 0 ?
- LMB_LFENCE : LMB_MFENCE);
+ lfence();
}
static void
-init_fence(void)
+rdtsc_mb_mfence(void)
{
-#if defined(__i386__)
- u_int cpuid_supported, p[4];
- lfence_works = LMB_NONE;
- __asm __volatile(
- " pushfl\n"
- " popl %%eax\n"
- " movl %%eax,%%ecx\n"
- " xorl $0x200000,%%eax\n"
- " pushl %%eax\n"
- " popfl\n"
- " pushfl\n"
- " popl %%eax\n"
- " xorl %%eax,%%ecx\n"
- " je 1f\n"
- " movl $1,%0\n"
- " jmp 2f\n"
- "1: movl $0,%0\n"
- "2:\n"
- : "=r" (cpuid_supported) : : "eax", "ecx", "cc");
- if (cpuid_supported) {
- cpuidp(0x1, p);
- if ((p[3] & CPUID_SSE2) != 0)
- lfence_works = select_lmb();
- }
-#elif defined(__amd64__)
- lfence_works = select_lmb();
-#else
-#error "Arch"
-#endif
+ mfence();
}
static void
-rdtsc_mb(void)
+rdtsc_mb_none(void)
{
+}
-again:
- if (__predict_true(lfence_works == LMB_LFENCE)) {
- lfence();
- return;
- } else if (lfence_works == LMB_MFENCE) {
- mfence();
- return;
- } else if (lfence_works == LMB_NONE) {
- return;
- }
- init_fence();
- goto again;
+DEFINE_UIFUNC(static, void, rdtsc_mb, (void), static)
+{
+ u_int p[4];
+ /* Not a typo, string matches our cpuidp() registers use. */
+ static const char intel_id[] = "GenuntelineI";
+
+ if ((cpu_feature & CPUID_SSE2) == 0)
+ return (rdtsc_mb_none);
+ cpuidp(0, p);
+ return (memcmp(p + 1, intel_id, sizeof(intel_id) - 1) == 0 ?
+ rdtsc_mb_lfence : rdtsc_mb_mfence);
}
static u_int
More information about the svn-src-stable-12
mailing list