aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorNate Lawson <njl@FreeBSD.org>2005-02-05 23:16:27 +0000
committerNate Lawson <njl@FreeBSD.org>2005-02-05 23:16:27 +0000
commit959c26396c1335efde43ade9982fab9bb9c72d8b (patch)
tree0e1f039adcdea95909bcd77418b2001d569179ae /sys/amd64
parent76ce4cc4565caa2f0ad658462bd00021f1a51cb4 (diff)
downloadsrc-959c26396c1335efde43ade9982fab9bb9c72d8b.tar.gz
src-959c26396c1335efde43ade9982fab9bb9c72d8b.zip
Make cpu_est_clockrate() more accurate by disabling interrupts for the
millisecond it is calibrating. Suggested by jhb@ and bde@. Don't clobber the tsc_freq with the new value since it isn't accurate enough for timecounters and the timecounter system as a whole needs support for changing rates before we do this. Subtract 0.5% from our measurement to account for overhead in DELAY. Note that this interface is for estimating the clockrate and needs to work well at runtime so doing a full calibration including disabling interrupts for a second is not feasible.
Notes
Notes: svn path=/head/; revision=141374
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 527c61bd1dbb..422c0fb949d2 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -456,6 +456,7 @@ cpu_boot(int howto)
int
cpu_est_clockrate(int cpu_id, uint64_t *rate)
{
+ register_t reg;
uint64_t tsc1, tsc2;
if (pcpu_find(cpu_id) == NULL || rate == NULL)
@@ -475,9 +476,11 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
#endif
/* Calibrate by measuring a short delay. */
+ reg = intr_disable();
tsc1 = rdtsc();
DELAY(1000);
tsc2 = rdtsc();
+ intr_restore(reg);
#ifdef SMP
mtx_lock_spin(&sched_lock);
@@ -485,8 +488,13 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
mtx_unlock_spin(&sched_lock);
#endif
- tsc_freq = (tsc2 - tsc1) * 1000;
- *rate = tsc_freq;
+ /*
+ * Calculate the difference in readings, convert to Mhz, and
+ * subtract 0.5% of the total. Empirical testing has shown that
+ * overhead in DELAY() works out to approximately this value.
+ */
+ tsc2 -= tsc1;
+ *rate = tsc2 * 1000 - tsc2 * 5;
return (0);
}