Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: rdmsr(MSR_TSC) vs rdtsc



On Tue, Feb 01, 2011 at 06:47:31PM +0100, Manuel Bouyer wrote:
> On Mon, Jan 31, 2011 at 11:22:38AM +0000, Andrew Doran wrote:
> > > How could this be fixed ? I guess we'll have to use rdmsr(MSR_TSC)
> > > or cpu_counter() depending on the CPU ?
> > 
> > How about another routine like cpu_counter_serializing() or something
> > that does a test and picks which one to use?
> 
> maybe somthing lilke the attached patch ?

Looks fine to me, thanks.

> 
> -- 
> Manuel Bouyer <bouyer%antioche.eu.org@localhost>
>      NetBSD: 26 ans d'experience feront toujours la difference
> --

> Index: include/cpu_counter.h
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/x86/include/cpu_counter.h,v
> retrieving revision 1.4
> diff -u -p -u -r1.4 cpu_counter.h
> --- include/cpu_counter.h     10 May 2008 16:12:32 -0000      1.4
> +++ include/cpu_counter.h     1 Feb 2011 17:35:50 -0000
> @@ -35,6 +35,7 @@
>  #ifdef _KERNEL
>  
>  uint64_t     cpu_counter(void);
> +uint64_t     cpu_counter_serializing(void);
>  uint32_t     cpu_counter32(void);
>  uint64_t     cpu_frequency(struct cpu_info *);
>  int          cpu_hascounter(void);
> Index: x86/cpu.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/x86/x86/cpu.c,v
> retrieving revision 1.79
> diff -u -p -u -r1.79 cpu.c
> --- x86/cpu.c 11 Jan 2011 18:25:25 -0000      1.79
> +++ x86/cpu.c 1 Feb 2011 17:35:50 -0000
> @@ -1080,10 +1080,12 @@ cpu_get_tsc_freq(struct cpu_info *ci)
>       uint64_t last_tsc;
>  
>       if (cpu_hascounter()) {
> -             last_tsc = rdmsr(MSR_TSC);
> +             last_tsc = cpu_counter_serializing();
>               i8254_delay(100000);
> -             ci->ci_data.cpu_cc_freq = (rdmsr(MSR_TSC) - last_tsc) * 10;
> +             ci->ci_data.cpu_cc_freq =
> +                 (cpu_counter_serializing() - last_tsc) * 10;
>       }
> +     printf("\n");
>  }
>  
>  void
> Index: x86/tsc.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/x86/x86/tsc.c,v
> retrieving revision 1.27
> diff -u -p -u -r1.27 tsc.c
> --- x86/tsc.c 21 Aug 2010 01:57:34 -0000      1.27
> +++ x86/tsc.c 1 Feb 2011 17:35:50 -0000
> @@ -177,13 +177,13 @@ tsc_read_bp(struct cpu_info *ci, uint64_
>  
>       /* Flag it and read our TSC. */
>       atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC);
> -     bptsc = rdmsr(MSR_TSC) >> 1;
> +     bptsc = cpu_counter_serializing() >> 1;
>  
>       /* Wait for remote to complete, and read ours again. */
>       while ((ci->ci_flags & CPUF_SYNCTSC) != 0) {
>               __insn_barrier();
>       }
> -     bptsc += (rdmsr(MSR_TSC) >> 1);
> +     bptsc += (cpu_counter_serializing() >> 1);
>  
>       /* Wait for the results to come in. */
>       while (tsc_sync_cpu == ci) {
> @@ -222,11 +222,11 @@ tsc_post_ap(struct cpu_info *ci)
>       while ((ci->ci_flags & CPUF_SYNCTSC) == 0) {
>               __insn_barrier();
>       }
> -     tsc = (rdmsr(MSR_TSC) >> 1);
> +     tsc = (cpu_counter_serializing() >> 1);
>  
>       /* Instruct primary to read its counter. */
>       atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC);
> -     tsc += (rdmsr(MSR_TSC) >> 1);
> +     tsc += (cpu_counter_serializing() >> 1);
>  
>       /* Post result.  Ensure the whole value goes out atomically. */
>       (void)atomic_swap_64(&tsc_sync_val, tsc);
> @@ -257,3 +257,12 @@ cpu_hascounter(void)
>  
>       return cpu_feature[0] & CPUID_TSC;
>  }
> +
> +uint64_t
> +cpu_counter_serializing(void)
> +{
> +     if (cpu_feature[0] & CPUID_MSR)
> +             return rdmsr(MSR_TSC);
> +     else
> +             return cpu_counter();
> +}



Home | Main Index | Thread Index | Old Index