Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jul 2012 13:21:30 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Andriy Gapon <avg@freebsd.org>
Cc:        svn-src-head@freebsd.org, Jim Harris <jimharris@freebsd.org>, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r238755 - head/sys/x86/x86
Message-ID:  <20120725102130.GH2676@deviant.kiev.zoral.com.ua>
In-Reply-To: <500F9E22.4080608@FreeBSD.org>
References:  <201207242210.q6OMACqV079603@svn.freebsd.org> <500F9E22.4080608@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--1Dj3cEIIrBZAiNOW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Jul 25, 2012 at 10:20:02AM +0300, Andriy Gapon wrote:
> on 25/07/2012 01:10 Jim Harris said the following:
> > Author: jimharris
> > Date: Tue Jul 24 22:10:11 2012
> > New Revision: 238755
> > URL: http://svn.freebsd.org/changeset/base/238755
> >=20
> > Log:
> >   Add rmb() to tsc_read_##x to enforce serialization of rdtsc captures.
> >  =20
> >   Intel Architecture Manual specifies that rdtsc instruction is not ser=
ialized,
> >   so without this change, TSC synchronization test would periodically f=
ail,
> >   resulting in use of HPET timecounter instead of TSC-low.  This caused
> >   severe performance degradation (40-50%) when running high IO/s worklo=
ads due to
> >   HPET MMIO reads and GEOM stat collection.
> >  =20
> >   Tests on Xeon E5-2600 (Sandy Bridge) 8C systems were seeing TSC synch=
ronization
> >   fail approximately 20% of the time.
>=20
> Should rather the synchronization test be fixed if it's the culprit?
Synchronization test for what ?

> Or is this change universally good for the real uses of TSC?

What I understood from the Intel SDM, and also from additional experiments
which Jim kindly made despite me being annoying as usual, is that 'read
memory barrier' AKA LFENCE there is used for its secondary implementation
effects, not for load/load barrier as you might assume.

According to SDM, LFENCE fully drains execution pipeline (but comparing
with MFENCE, does not drain write buffers). The result is that RDTSC is
not started before previous instructions are finished.

For tsc test, this means that after the change RDTSC executions are not
reordered on the single core among themself. As I understand, CPU has
no dependency noted between two reads of tsc by RDTSC, which allows
later read to give lower value of counter. This is fixed by Intel by
introduction of RDTSCP instruction, which is defined to be serialization
point, and use of which (instead of LFENCE; RDTSC sequence) also fixes
test, as confirmed by Jim.

In fact, I now think that we should also apply the following patch.
Otherwise, consequtive calls to e.g. binuptime(9) could return decreased
time stamps. Note that libc __vdso_gettc.c already has LFENCE nearby the
tsc reads, which was done not for this reason, but apparently needed for
the reason too.

diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
index 085c339..229b351 100644
--- a/sys/x86/x86/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -594,6 +594,7 @@ static u_int
 tsc_get_timecount(struct timecounter *tc __unused)
 {
=20
+	rmb();
 	return (rdtsc32());
 }
=20
@@ -602,8 +603,9 @@ tsc_get_timecount_low(struct timecounter *tc)
 {
 	uint32_t rv;
=20
+	rmb();
 	__asm __volatile("rdtsc; shrd %%cl, %%edx, %0"
-	: "=3Da" (rv) : "c" ((int)(intptr_t)tc->tc_priv) : "edx");
+	    : "=3Da" (rv) : "c" ((int)(intptr_t)tc->tc_priv) : "edx");
 	return (rv);
 }
=20

--1Dj3cEIIrBZAiNOW
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAlAPyKkACgkQC3+MBN1Mb4h5lgCfX7aUTYLRIMXAkkPPXxP8nS4Q
xmkAn2aZIRz0JMn3SWE6ifZOHUh7ZkHd
=ass/
-----END PGP SIGNATURE-----

--1Dj3cEIIrBZAiNOW--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120725102130.GH2676>