summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2008-10-21 00:38:00 +0000
committerjkim <jkim@FreeBSD.org>2008-10-21 00:38:00 +0000
commit0b6f0646dfbb4de594b633fb94d4e50e4376482c (patch)
tree7447b782629647c7d066b2eafea4fc939f49b09e /sys/amd64
parentd4d906ba8600be6372142965c16b1830772b3df9 (diff)
downloadFreeBSD-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.c13
-rw-r--r--sys/amd64/amd64/prof_machdep.c7
-rw-r--r--sys/amd64/amd64/tsc.c17
-rw-r--r--sys/amd64/include/clock.h1
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);
OpenPOWER on IntegriCloud