diff options
author | jkim <jkim@FreeBSD.org> | 2008-10-21 00:38:00 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2008-10-21 00:38:00 +0000 |
commit | 0b6f0646dfbb4de594b633fb94d4e50e4376482c (patch) | |
tree | 7447b782629647c7d066b2eafea4fc939f49b09e /sys/amd64 | |
parent | d4d906ba8600be6372142965c16b1830772b3df9 (diff) | |
download | FreeBSD-src-0b6f0646dfbb4de594b633fb94d4e50e4376482c.zip FreeBSD-src-0b6f0646dfbb4de594b633fb94d4e50e4376482c.tar.gz |
Turn off CPU frequency change notifiers when the TSC is P-state invariant
or it is forced by setting 'kern.timecounter.invariant_tsc' tunable
to non-zero.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/identcpu.c | 13 | ||||
-rw-r--r-- | sys/amd64/amd64/prof_machdep.c | 7 | ||||
-rw-r--r-- | sys/amd64/amd64/tsc.c | 17 | ||||
-rw-r--r-- | sys/amd64/include/clock.h | 1 |
4 files changed, 30 insertions, 8 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index 30ab367..5d5f401 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -347,6 +347,12 @@ printcpuinfo(void) "AuthenticAMD") == 0) cpu_feature &= ~CPUID_HTT; + if (!tsc_is_invariant && + (amd_pminfo & AMDPM_TSC_INVARIANT)) { + tsc_is_invariant = 1; + printf("\n P-state invariant TSC"); + } + /* * If this CPU supports HTT or CMP then mention the * number of physical/logical cores it contains. @@ -409,8 +415,11 @@ panicifcpuunsupported(void) static void tsc_freq_changed(void *arg, const struct cf_level *level, int status) { - /* If there was an error during the transition, don't do anything. */ - if (status != 0) + /* + * If there was an error during the transition or + * TSC is P-state invariant, don't do anything. + */ + if (status != 0 || tsc_is_invariant) return; /* Total setting for this level gives the new frequency in MHz. */ diff --git a/sys/amd64/amd64/prof_machdep.c b/sys/amd64/amd64/prof_machdep.c index dad52df..6c848df 100644 --- a/sys/amd64/amd64/prof_machdep.c +++ b/sys/amd64/amd64/prof_machdep.c @@ -383,8 +383,11 @@ static void tsc_freq_changed(void *arg, const struct cf_level *level, int status) { - /* If there was an error during the transition, don't do anything. */ - if (status != 0) + /* + * If there was an error during the transition or + * TSC is P-state invariant, don't do anything. + */ + if (status != 0 || tsc_is_invariant) return; if (cputime_prof_active && cputime_clock == CPUTIME_CLOCK_TSC) printf("warning: cpu freq changed while profiling active\n"); diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 3c66a33..dcda751 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -48,8 +48,13 @@ __FBSDID("$FreeBSD$"); uint64_t tsc_freq; int tsc_is_broken; +int tsc_is_invariant; static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag; +SYSCTL_INT(_kern_timecounter, OID_AUTO, invariant_tsc, CTLFLAG_RDTUN, + &tsc_is_invariant, 0, "Indicates whether the TSC is P-state invariant"); +TUNABLE_INT("kern.timecounter.invariant_tsc", &tsc_is_invariant); + #ifdef SMP static int smp_tsc; SYSCTL_INT(_kern_timecounter, OID_AUTO, smp_tsc, CTLFLAG_RDTUN, &smp_tsc, 0, @@ -174,11 +179,12 @@ static void tsc_freq_changing(void *arg, const struct cf_level *level, int *status) { - if (*status != 0 || timecounter != &tsc_timecounter) + if (*status != 0 || timecounter != &tsc_timecounter || + tsc_is_invariant) return; printf("timecounter TSC must not be in use when " - "changing frequencies; change denied\n"); + "changing frequencies; change denied\n"); *status = EBUSY; } @@ -186,8 +192,11 @@ tsc_freq_changing(void *arg, const struct cf_level *level, int *status) static void tsc_freq_changed(void *arg, const struct cf_level *level, int status) { - /* If there was an error during the transition, don't do anything. */ - if (status != 0) + /* + * If there was an error during the transition or + * TSC is P-state invariant, don't do anything. + */ + if (status != 0 || tsc_is_invariant) return; /* Total setting for this level gives the new frequency in MHz. */ diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index de09de3..f8745f9c 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -20,6 +20,7 @@ extern u_int i8254_freq; extern int i8254_max_count; extern uint64_t tsc_freq; extern int tsc_is_broken; +extern int tsc_is_invariant; void i8254_init(void); |