Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Jan 2009 20:53:37 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r187567 - in stable/7/sys: . amd64/amd64 amd64/include contrib/altq/altq contrib/pf dev/ath/ath_hal dev/cxgb i386/i386 i386/include i386/isa
Message-ID:  <200901212053.n0LKrbEt090963@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Wed Jan 21 20:53:36 2009
New Revision: 187567
URL: http://svn.freebsd.org/changeset/base/187567

Log:
  MFC: 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.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/identcpu.c
  stable/7/sys/amd64/amd64/prof_machdep.c
  stable/7/sys/amd64/amd64/tsc.c
  stable/7/sys/amd64/include/clock.h
  stable/7/sys/contrib/altq/altq/altq_subr.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/i386/i386/identcpu.c
  stable/7/sys/i386/i386/tsc.c
  stable/7/sys/i386/include/clock.h
  stable/7/sys/i386/isa/prof_machdep.c

Modified: stable/7/sys/amd64/amd64/identcpu.c
==============================================================================
--- stable/7/sys/amd64/amd64/identcpu.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/amd64/amd64/identcpu.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -345,6 +345,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.
@@ -405,8 +411,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. */

Modified: stable/7/sys/amd64/amd64/prof_machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/prof_machdep.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/amd64/amd64/prof_machdep.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -387,8 +387,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");

Modified: stable/7/sys/amd64/amd64/tsc.c
==============================================================================
--- stable/7/sys/amd64/amd64/tsc.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/amd64/amd64/tsc.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -53,8 +53,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,
@@ -179,11 +184,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;
 }
 
@@ -191,8 +197,11 @@ tsc_freq_changing(void *arg, const struc
 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. */

Modified: stable/7/sys/amd64/include/clock.h
==============================================================================
--- stable/7/sys/amd64/include/clock.h	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/amd64/include/clock.h	Wed Jan 21 20:53:36 2009	(r187567)
@@ -22,6 +22,7 @@ extern u_int	timer_freq;
 extern int	timer0_max_count;
 extern uint64_t	tsc_freq;
 extern int	tsc_is_broken;
+extern int	tsc_is_invariant;
 
 void	i8254_init(void);
 

Modified: stable/7/sys/contrib/altq/altq/altq_subr.c
==============================================================================
--- stable/7/sys/contrib/altq/altq/altq_subr.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/contrib/altq/altq/altq_subr.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -910,6 +910,12 @@ tsc_freq_changed(void *arg, const struct
 	if (status != 0)
 		return;
 
+#if (__FreeBSD_version >= 701102) && (defined(__amd64__) || defined(__i386__))
+	/* If TSC is P-state invariant, don't do anything. */
+	if (tsc_is_invariant)
+		return;
+#endif
+
 	/* Total setting for this level gives the new frequency in MHz. */
 	init_machclk();
 }

Modified: stable/7/sys/i386/i386/identcpu.c
==============================================================================
--- stable/7/sys/i386/i386/identcpu.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/i386/i386/identcpu.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -842,6 +842,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.
@@ -1058,8 +1064,11 @@ identifycyrix(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. */

Modified: stable/7/sys/i386/i386/tsc.c
==============================================================================
--- stable/7/sys/i386/i386/tsc.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/i386/i386/tsc.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -48,9 +48,14 @@ __FBSDID("$FreeBSD$");
 
 uint64_t	tsc_freq;
 int		tsc_is_broken;
+int		tsc_is_invariant;
 u_int		tsc_present;
 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,
@@ -198,11 +203,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;
 }
 
@@ -210,8 +216,11 @@ tsc_freq_changing(void *arg, const struc
 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. */

Modified: stable/7/sys/i386/include/clock.h
==============================================================================
--- stable/7/sys/i386/include/clock.h	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/i386/include/clock.h	Wed Jan 21 20:53:36 2009	(r187567)
@@ -22,6 +22,7 @@ extern u_int	timer_freq;
 extern int	timer0_max_count;
 extern uint64_t	tsc_freq;
 extern int	tsc_is_broken;
+extern int	tsc_is_invariant;
 
 void	i8254_init(void);
 

Modified: stable/7/sys/i386/isa/prof_machdep.c
==============================================================================
--- stable/7/sys/i386/isa/prof_machdep.c	Wed Jan 21 20:44:42 2009	(r187566)
+++ stable/7/sys/i386/isa/prof_machdep.c	Wed Jan 21 20:53:36 2009	(r187567)
@@ -357,8 +357,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");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901212053.n0LKrbEt090963>