diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/tsc_32.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index f04d08a7d022..9ebc0dab66b4 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c | |||
@@ -137,31 +137,37 @@ unsigned long native_calculate_cpu_khz(void) | |||
137 | 137 | ||
138 | local_irq_save(flags); | 138 | local_irq_save(flags); |
139 | 139 | ||
140 | /* run 3 times to ensure the cache is warm */ | 140 | /* run 3 times to ensure the cache is warm and to get an accurate reading */ |
141 | for (i = 0; i < 3; i++) { | 141 | for (i = 0; i < 3; i++) { |
142 | mach_prepare_counter(); | 142 | mach_prepare_counter(); |
143 | rdtscll(start); | 143 | rdtscll(start); |
144 | mach_countup(&count); | 144 | mach_countup(&count); |
145 | rdtscll(end); | 145 | rdtscll(end); |
146 | |||
147 | /* | ||
148 | * Error: ECTCNEVERSET | ||
149 | * The CTC wasn't reliable: we got a hit on the very first read, | ||
150 | * or the CPU was so fast/slow that the quotient wouldn't fit in | ||
151 | * 32 bits.. | ||
152 | */ | ||
153 | if (count <= 1) | ||
154 | continue; | ||
155 | |||
156 | /* cpu freq too slow: */ | ||
157 | if ((end - start) <= CALIBRATE_TIME_MSEC) | ||
158 | continue; | ||
159 | |||
160 | /* | ||
161 | * We want the minimum time of all runs in case one of them | ||
162 | * is inaccurate due to SMI or other delay | ||
163 | */ | ||
146 | delta64 = min(delta64, (end - start)); | 164 | delta64 = min(delta64, (end - start)); |
147 | } | 165 | } |
148 | /* | ||
149 | * Error: ECTCNEVERSET | ||
150 | * The CTC wasn't reliable: we got a hit on the very first read, | ||
151 | * or the CPU was so fast/slow that the quotient wouldn't fit in | ||
152 | * 32 bits.. | ||
153 | */ | ||
154 | if (count <= 1) | ||
155 | goto err; | ||
156 | 166 | ||
157 | /* cpu freq too fast: */ | 167 | /* cpu freq too fast (or every run was bad): */ |
158 | if (delta64 > (1ULL<<32)) | 168 | if (delta64 > (1ULL<<32)) |
159 | goto err; | 169 | goto err; |
160 | 170 | ||
161 | /* cpu freq too slow: */ | ||
162 | if (delta64 <= CALIBRATE_TIME_MSEC) | ||
163 | goto err; | ||
164 | |||
165 | delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ | 171 | delta64 += CALIBRATE_TIME_MSEC/2; /* round for do_div */ |
166 | do_div(delta64,CALIBRATE_TIME_MSEC); | 172 | do_div(delta64,CALIBRATE_TIME_MSEC); |
167 | 173 | ||