Port-amd64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: rdmsr(MSR_TSC) vs rdtsc
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 ?
--
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