From owner-svn-src-all@FreeBSD.ORG Tue Oct 21 00:38:00 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D97201065672; Tue, 21 Oct 2008 00:38:00 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C5B948FC0C; Tue, 21 Oct 2008 00:38:00 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id m9L0c0Nx084570; Tue, 21 Oct 2008 00:38:00 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m9L0c0w1084560; Tue, 21 Oct 2008 00:38:00 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <200810210038.m9L0c0w1084560@svn.freebsd.org> From: Jung-uk Kim Date: Tue, 21 Oct 2008 00:38:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184102 - in head/sys: amd64/amd64 amd64/include contrib/altq/altq i386/i386 i386/include i386/isa X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Oct 2008 00:38:01 -0000 Author: jkim Date: Tue Oct 21 00:38:00 2008 New Revision: 184102 URL: http://svn.freebsd.org/changeset/base/184102 Log: 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: head/sys/amd64/amd64/identcpu.c head/sys/amd64/amd64/prof_machdep.c head/sys/amd64/amd64/tsc.c head/sys/amd64/include/clock.h head/sys/contrib/altq/altq/altq_subr.c head/sys/i386/i386/identcpu.c head/sys/i386/i386/tsc.c head/sys/i386/include/clock.h head/sys/i386/isa/prof_machdep.c Modified: head/sys/amd64/amd64/identcpu.c ============================================================================== --- head/sys/amd64/amd64/identcpu.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/amd64/amd64/identcpu.c Tue Oct 21 00:38:00 2008 (r184102) @@ -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. */ Modified: head/sys/amd64/amd64/prof_machdep.c ============================================================================== --- head/sys/amd64/amd64/prof_machdep.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/amd64/amd64/prof_machdep.c Tue Oct 21 00:38:00 2008 (r184102) @@ -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"); Modified: head/sys/amd64/amd64/tsc.c ============================================================================== --- head/sys/amd64/amd64/tsc.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/amd64/amd64/tsc.c Tue Oct 21 00:38:00 2008 (r184102) @@ -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 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: head/sys/amd64/include/clock.h ============================================================================== --- head/sys/amd64/include/clock.h Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/amd64/include/clock.h Tue Oct 21 00:38:00 2008 (r184102) @@ -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); Modified: head/sys/contrib/altq/altq/altq_subr.c ============================================================================== --- head/sys/contrib/altq/altq/altq_subr.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/contrib/altq/altq/altq_subr.c Tue Oct 21 00:38:00 2008 (r184102) @@ -909,6 +909,12 @@ tsc_freq_changed(void *arg, const struct if (status != 0) return; +#if (__FreeBSD_version >= 800050) && (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: head/sys/i386/i386/identcpu.c ============================================================================== --- head/sys/i386/i386/identcpu.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/i386/i386/identcpu.c Tue Oct 21 00:38:00 2008 (r184102) @@ -841,6 +841,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. @@ -1059,8 +1065,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: head/sys/i386/i386/tsc.c ============================================================================== --- head/sys/i386/i386/tsc.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/i386/i386/tsc.c Tue Oct 21 00:38:00 2008 (r184102) @@ -48,9 +48,13 @@ __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 the TSC is P-state invariant"); + #ifdef SMP static int smp_tsc; SYSCTL_INT(_kern_timecounter, OID_AUTO, smp_tsc, CTLFLAG_RDTUN, &smp_tsc, 0, @@ -107,8 +111,9 @@ init_TSC(void) set_cputicker(rdtsc, tsc_freq, 1); /* Register to find out about changes in CPU frequency. */ - tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change, - tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST); + if (!tsc_is_invariant) + tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change, + tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST); tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change, tsc_freq_changed, NULL, EVENTHANDLER_PRI_FIRST); tsc_levels_tag = EVENTHANDLER_REGISTER(cpufreq_levels_changed, @@ -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: head/sys/i386/include/clock.h ============================================================================== --- head/sys/i386/include/clock.h Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/i386/include/clock.h Tue Oct 21 00:38:00 2008 (r184102) @@ -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); Modified: head/sys/i386/isa/prof_machdep.c ============================================================================== --- head/sys/i386/isa/prof_machdep.c Tue Oct 21 00:17:55 2008 (r184101) +++ head/sys/i386/isa/prof_machdep.c Tue Oct 21 00:38:00 2008 (r184102) @@ -353,8 +353,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");