Date: Sun, 13 Aug 2017 15:13:11 +0200 From: Andre Albsmeier <andre@fbsd.e4m.org> To: Konstantin Belousov <kib@FreeBSD.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org, andre@fbsd.e4m.org Subject: Re: svn commit: r322345 - stable/11/lib/libc/x86/sys Message-ID: <20170813131311.GA24473@voyager> In-Reply-To: <201708100900.v7A90FjI094474@repo.freebsd.org> References: <201708100900.v7A90FjI094474@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 10-Aug-2017 at 09:00:15 +0000, Konstantin Belousov wrote: > Author: kib > Date: Thu Aug 10 09:00:15 2017 > New Revision: 322345 > URL: https://svnweb.freebsd.org/changeset/base/322345 > > Log: > MFC r321608: > Use MFENCE to serialize RDTSC on non-Intel CPUs. This broke libc on my FreeBSD clang version 4.0.0 (tags/RELEASE_400/final 297347) (based on LLVM 4.0.0) VT(vga): text 80x25 CPU: AMD-K6tm w/ multimedia extensions (199.44-MHz 586-class CPU) Origin="AuthenticAMD" Id=0x562 Family=0x5 Model=0x6 Stepping=2 Features=0x8001bf<FPU,VME,DE,PSE,TSC,MSR,MCE,CX8,MMX> AMD Features=0x400<<b10>> On system start, it actually makes various programmes hang until Ctrl-C is pressed. Reboot is not possible (endlessly hanging with 'zillions of defunct processes). Going back to r322042 fixes it... -Andre > > Modified: > stable/11/lib/libc/x86/sys/__vdso_gettc.c > Directory Properties: > stable/11/ (props changed) > > Modified: stable/11/lib/libc/x86/sys/__vdso_gettc.c > ============================================================================== > --- stable/11/lib/libc/x86/sys/__vdso_gettc.c Thu Aug 10 06:59:43 2017 (r322344) > +++ stable/11/lib/libc/x86/sys/__vdso_gettc.c Thu Aug 10 09:00:15 2017 (r322345) > @@ -52,57 +52,108 @@ __FBSDID("$FreeBSD$"); > #endif > #include "libc_private.h" > > +static enum LMB { > + LMB_UNKNOWN, > + LMB_NONE, > + LMB_MFENCE, > + LMB_LFENCE > +} lfence_works = LMB_UNKNOWN; > + > static void > -lfence_mb(void) > +cpuidp(u_int leaf, u_int p[4]) > { > + > + __asm __volatile( > #if defined(__i386__) > - static int lfence_works = -1; > + " pushl %%ebx\n" > +#endif > + " cpuid\n" > +#if defined(__i386__) > + " movl %%ebx,%1\n" > + " popl %%ebx" > +#endif > + : "=a" (p[0]), > +#if defined(__i386__) > + "=r" (p[1]), > +#elif defined(__amd64__) > + "=b" (p[1]), > +#else > +#error "Arch" > +#endif > + "=c" (p[2]), "=d" (p[3]) > + : "0" (leaf)); > +} > + > +static enum LMB > +select_lmb(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); > +} > + > +static void > +init_fence(void) > +{ > +#if defined(__i386__) > u_int cpuid_supported, p[4]; > > - if (lfence_works == -1) { > - __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) { > - __asm __volatile( > - " pushl %%ebx\n" > - " cpuid\n" > - " movl %%ebx,%1\n" > - " popl %%ebx\n" > - : "=a" (p[0]), "=r" (p[1]), "=c" (p[2]), "=d" (p[3]) > - : "0" (0x1)); > - lfence_works = (p[3] & CPUID_SSE2) != 0; > - } else > - lfence_works = 0; > - } > - if (lfence_works == 1) > - lfence(); > + __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(); > + } else > + lfence_works = LMB_NONE; > #elif defined(__amd64__) > - lfence(); > + lfence_works = select_lmb(); > #else > -#error "arch" > +#error "Arch" > #endif > } > > +static void > +rdtsc_mb(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; > +} > + > static u_int > __vdso_gettc_rdtsc_low(const struct vdso_timehands *th) > { > u_int rv; > > - lfence_mb(); > + rdtsc_mb(); > __asm __volatile("rdtsc; shrd %%cl, %%edx, %0" > : "=a" (rv) : "c" (th->th_x86_shift) : "edx"); > return (rv); > @@ -112,7 +163,7 @@ static u_int > __vdso_rdtsc32(void) > { > > - lfence_mb(); > + rdtsc_mb(); > return (rdtsc32()); > } > > @@ -211,7 +262,7 @@ __vdso_hyperv_tsc(struct hyperv_reftsc *tsc_ref, u_int > scale = tsc_ref->tsc_scale; > ofs = tsc_ref->tsc_ofs; > > - lfence_mb(); > + rdtsc_mb(); > tsc = rdtsc(); > > /* ret = ((tsc * scale) >> 64) + ofs */ > _______________________________________________ > svn-src-stable-11@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/svn-src-stable-11 > To unsubscribe, send any mail to "svn-src-stable-11-unsubscribe@freebsd.org" -- Stuxnet? Find ich gut. Manche lernen nur auf die harte Tour...
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170813131311.GA24473>