Re: svn commit: r238973 - head/sys/x86/x86

2012-08-06 Thread Doug Barton
On 08/06/2012 07:12 AM, Steve Kargl wrote:
> On Mon, Aug 06, 2012 at 12:08:36AM -0700, Doug Barton wrote:
>> -BEGIN PGP SIGNED MESSAGE-
>> Hash: SHA256
>>
>> On 08/01/2012 10:32, Konstantin Belousov wrote:
>>> It should have been the text
>>
>> Forced commit? :)
>>
> 
> Try 'svn log sys/x86/x86/tsc.c | more'

Awesome. :)

___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r238973 - head/sys/x86/x86

2012-08-06 Thread Steve Kargl
On Mon, Aug 06, 2012 at 12:08:36AM -0700, Doug Barton wrote:
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA256
> 
> On 08/01/2012 10:32, Konstantin Belousov wrote:
> > It should have been the text
> 
> Forced commit? :)
> 

Try 'svn log sys/x86/x86/tsc.c | more'

-- 
Steve
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r238973 - head/sys/x86/x86

2012-08-06 Thread Doug Barton
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

On 08/01/2012 10:32, Konstantin Belousov wrote:
> It should have been the text

Forced commit? :)

- -- 

I am only one, but I am one.  I cannot do everything, but I can do
something.  And I will not let what I cannot do interfere with what
I can do.
-- Edward Everett Hale, (1822 - 1909)
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.19 (FreeBSD)

iQEcBAEBCAAGBQJQH210AAoJEFzGhvEaGryEQ/8H/jTrpM5C8TiyxU4A3wTieeUx
1IlDUpRaiLO65u6iWE2/NcxstL2QOnBHNmuIDSZ3MCDf7ytlH8XuDkEA0kj54zlK
/evgsR4wP9us53lWtLPG4PUcKtjU0iZ10lP4iGENbdP/5pf/pbT1sZ7NDqeXajT/
RrwiIipgdCwZRqQ9MaU/3EUUH1gA40Y7Wohm6gRT0rFEBOHagjpIpOW1oPPmNSjE
TJW30JDJXkccCn3BGjcPA93zhPcW1Hg+O6Ekr88gTp2SdGDgHhI6O27j/2zN/xgZ
GjFHVlynA4p3a+e9sfi4j0b3jLVaoz5vyaWPJmeHfKpP02wxUL9l44AF/ErodpA=
=GiTg
-END PGP SIGNATURE-
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r238973 - head/sys/x86/x86

2012-08-01 Thread Konstantin Belousov
On Wed, Aug 01, 2012 at 05:26:22PM +, Konstantin Belousov wrote:
> Author: kib
> Date: Wed Aug  1 17:26:22 2012
> New Revision: 238973
> URL: http://svn.freebsd.org/changeset/base/238973
> 
> Log:
>   diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
>   index c253a96..3d8bd30 100644
>   --- a/sys/x86/x86/tsc.c

Oops, I managed to do it: committing with the diff itself as commit log
instead of the log message. Sorry.

It should have been the text

Rdtsc instruction is not synchronized, it seems on some Intel cores it
can bypass even the locked instructions.  As a result, rdtsc executed
on different cores may return unordered TSC values even when the rdtsc
appearance in the instruction sequences is provably ordered.

Similarly to what has been done in r238755 for TSC synchronization
test, add explicit fences right before rdtsc in the timecounters 'get'
functions.  Intel recommends to use LFENCE, while AMD refers to
MFENCE. For VIA follow what Linux does and use LFENCE.  With this
change, I see no reordered reads of TSC on Nehalem.

Change the rmb() to inlined CPUID in the SMP TSC synchronization test.
On i386, locked instruction is used for rmb(), and as noted earlier,
it is not enough. Since i386 machine may not support SSE2, do simplest
possible synchronization with CPUID.

MFC after:1 week
Discussed with:   avg, bde, jkim


pgp8kvg6xvZya.pgp
Description: PGP signature


svn commit: r238973 - head/sys/x86/x86

2012-08-01 Thread Konstantin Belousov
Author: kib
Date: Wed Aug  1 17:26:22 2012
New Revision: 238973
URL: http://svn.freebsd.org/changeset/base/238973

Log:
  diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
  index c253a96..3d8bd30 100644
  --- a/sys/x86/x86/tsc.c
  +++ b/sys/x86/x86/tsc.c
  @@ -82,7 +82,11 @@ static void tsc_freq_changed(void *arg, const struct 
cf_level *level,
   static void tsc_freq_changing(void *arg, const struct cf_level *level,
   int *status);
   static unsigned tsc_get_timecount(struct timecounter *tc);
  -static unsigned tsc_get_timecount_low(struct timecounter *tc);
  +static inline unsigned tsc_get_timecount_low(struct timecounter *tc);
  +static unsigned tsc_get_timecount_lfence(struct timecounter *tc);
  +static unsigned tsc_get_timecount_low_lfence(struct timecounter *tc);
  +static unsigned tsc_get_timecount_mfence(struct timecounter *tc);
  +static unsigned tsc_get_timecount_low_mfence(struct timecounter *tc);
   static void tsc_levels_changed(void *arg, int unit);
  
   static struct timecounter tsc_timecounter = {
  @@ -262,6 +266,10 @@ probe_tsc_freq(void)
(vm_guest == VM_GUEST_NO &&
CPUID_TO_FAMILY(cpu_id) >= 0x10))
tsc_is_invariant = 1;
  + if (cpu_feature & CPUID_SSE2) {
  + tsc_timecounter.tc_get_timecount =
  + tsc_get_timecount_mfence;
  + }
break;
case CPU_VENDOR_INTEL:
if ((amd_pminfo & AMDPM_TSC_INVARIANT) != 0 ||
  @@ -271,6 +279,10 @@ probe_tsc_freq(void)
(CPUID_TO_FAMILY(cpu_id) == 0xf &&
CPUID_TO_MODEL(cpu_id) >= 0x3
tsc_is_invariant = 1;
  + if (cpu_feature & CPUID_SSE2) {
  + tsc_timecounter.tc_get_timecount =
  + tsc_get_timecount_lfence;
  + }
break;
case CPU_VENDOR_CENTAUR:
if (vm_guest == VM_GUEST_NO &&
  @@ -278,6 +290,10 @@ probe_tsc_freq(void)
CPUID_TO_MODEL(cpu_id) >= 0xf &&
(rdmsr(0x1203) & 0x1ULL) == 0)
tsc_is_invariant = 1;
  + if (cpu_feature & CPUID_SSE2) {
  + tsc_timecounter.tc_get_timecount =
  + tsc_get_timecount_lfence;
  + }
break;
}
  
  @@ -328,16 +344,31 @@ 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)  \
  -{\
  - uint32_t *tsc = arg;\
  - u_int cpu = PCPU_GET(cpuid);\
  - \
  - rmb();  \
  - tsc[cpu * 3 + x] = rdtsc32();   \
  +/*
  + * RDTSC is not a serializing instruction, and does not drain
  + * instruction stream, so we need to drain the stream before executing
  + * it.  It could be fixed by use of RDTSCP, except the instruction is
  + * not available everywhere.
  + *
  + * Use CPUID for draining in the boot-time SMP constistency test.  The
  + * timecounters use MFENCE for AMD CPUs, and LFENCE for others (Intel
  + * and VIA) when SSE2 is present, and nothing on older machines which
  + * also do not issue RDTSC prematurely.  There, testing for SSE2 and
  + * vendor is too cumbersome, and we learn about TSC presence from
  + * CPUID.
  + *
  + * Do not use do_cpuid(), since we do not need CPUID results, which
  + * have to be written into memory with do_cpuid().
  + */
  +#define  TSC_READ(x) 
\
  +static void  \
  +tsc_read_##x(void *arg)  
\
  +{\
  + uint32_t *tsc = arg;\
  + u_int cpu = PCPU_GET(cpuid);\
  + \
  + __asm __volatile("cpuid" : : : "eax", "ebx", "ecx", "edx"); \
  + tsc[cpu * 3 + x] = rdtsc32();   \
   }
   TSC_READ(0)
   TSC_READ(1)
  @@ -487,7 +518,16 @@ init:
for (shift = 0; shift < 31 && (tsc_freq >> shift) > max_freq; shift++)
;
if (shift > 0) {
  - tsc_timecounter.tc_get_timecount = tsc_get_timecount_low;
  + if (cpu_feature & CPUID_SSE2) {
  + if (cpu_vendor_id == CPU_VENDOR_AMD) {
  + tsc_timecounter.tc_get_timecount =
  + tsc_get_timecount_low_mfence;
  + } else {
  + tsc_timecounter.tc_get_t