svn commit: r205875 - in stable/8/sys: amd64/amd64 amd64/include amd64/isa i386/i386 i386/include i386/isa pc98/cbus

Attilio Rao attilio at FreeBSD.org
Tue Mar 30 11:19:31 UTC 2010


Author: attilio
Date: Tue Mar 30 11:19:29 2010
New Revision: 205875
URL: http://svn.freebsd.org/changeset/base/205875

Log:
  MFC r204641, r204753:
  Improving the clocks auto-tunning by firstly checking if the atrtc may be
  correctly initialized and just then assign to softclock/profclock.
  
  Sponsored by:   Sandvine Incorporated

Modified:
  stable/8/sys/amd64/amd64/local_apic.c
  stable/8/sys/amd64/include/apicvar.h
  stable/8/sys/amd64/isa/clock.c
  stable/8/sys/i386/i386/local_apic.c
  stable/8/sys/i386/include/apicvar.h
  stable/8/sys/i386/isa/clock.c
  stable/8/sys/pc98/cbus/clock.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/amd64/amd64/local_apic.c
==============================================================================
--- stable/8/sys/amd64/amd64/local_apic.c	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/amd64/amd64/local_apic.c	Tue Mar 30 11:19:29 2010	(r205875)
@@ -149,6 +149,7 @@ extern inthand_t IDTVEC(rsvd);
 volatile lapic_t *lapic;
 vm_paddr_t lapic_paddr;
 static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
+static enum lapic_clock clockcoverage;
 
 static void	lapic_enable(void);
 static void	lapic_resume(struct pic *pic);
@@ -160,9 +161,6 @@ static uint32_t	lvt_mode(struct lapic *l
 
 struct pic lapic_pic = { .pic_resume = lapic_resume };
 
-static int lapic_allclocks;
-TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
-
 static uint32_t
 lvt_mode(struct lapic *la, u_int pin, uint32_t value)
 {
@@ -423,17 +421,20 @@ lapic_disable_pmc(void)
  * local APIC only for the hardclock and 0 if none of them can be handled.
  */
 enum lapic_clock
-lapic_setup_clock(void)
+lapic_setup_clock(enum lapic_clock srcsdes)
 {
 	u_long value;
 	int i;
 
-	/* Can't drive the timer without a local APIC. */
-	if (lapic == NULL)
-		return (LAPIC_CLOCK_NONE);
+	/* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */
+	MPASS(srcsdes != LAPIC_CLOCK_NONE);
 
-	if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)
-		return (LAPIC_CLOCK_NONE);
+	/* Can't drive the timer without a local APIC. */
+	if (lapic == NULL ||
+	    (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) {
+		clockcoverage = LAPIC_CLOCK_NONE;
+		return (clockcoverage);
+	}
 
 	/* Start off with a divisor of 2 (power on reset default). */
 	lapic_timer_divisor = 2;
@@ -469,7 +470,7 @@ lapic_setup_clock(void)
 	 * Please note that stathz and profhz are set only if all the
 	 * clocks are handled through the local APIC.
 	 */
-	if (lapic_allclocks != 0) {
+	if (srcsdes == LAPIC_CLOCK_ALL) {
 		if (hz >= 1500)
 			lapic_timer_hz = hz;
 		else if (hz >= 750)
@@ -479,7 +480,7 @@ lapic_setup_clock(void)
 	} else
 		lapic_timer_hz = hz;
 	lapic_timer_period = value / lapic_timer_hz;
-	if (lapic_allclocks != 0) {
+	if (srcsdes == LAPIC_CLOCK_ALL) {
 		if (lapic_timer_hz < 128)
 			stathz = lapic_timer_hz;
 		else
@@ -493,7 +494,8 @@ lapic_setup_clock(void)
 	 */
 	lapic_timer_periodic(lapic_timer_period);
 	lapic_timer_enable_intr();
-	return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL);
+	clockcoverage = srcsdes;
+	return (srcsdes);
 }
 
 void
@@ -796,7 +798,7 @@ lapic_handle_timer(struct trapframe *fra
 		else
 			hardclock_cpu(TRAPF_USERMODE(frame));
 	}
-	if (lapic_allclocks != 0) {
+	if (clockcoverage == LAPIC_CLOCK_ALL) {
 
 		/* Fire statclock at stathz. */
 		la->la_stat_ticks += stathz;

Modified: stable/8/sys/amd64/include/apicvar.h
==============================================================================
--- stable/8/sys/amd64/include/apicvar.h	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/amd64/include/apicvar.h	Tue Mar 30 11:19:29 2010	(r205875)
@@ -230,7 +230,7 @@ int	lapic_set_lvt_triggermode(u_int apic
 	    enum intr_trigger trigger);
 void	lapic_set_tpr(u_int vector);
 void	lapic_setup(int boot);
-enum lapic_clock	lapic_setup_clock(void);
+enum lapic_clock	lapic_setup_clock(enum lapic_clock srcsdes);
 
 #endif /* !LOCORE */
 #endif /* _MACHINE_APICVAR_H_ */

Modified: stable/8/sys/amd64/isa/clock.c
==============================================================================
--- stable/8/sys/amd64/isa/clock.c	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/amd64/isa/clock.c	Tue Mar 30 11:19:29 2010	(r205875)
@@ -84,6 +84,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq
 int	i8254_max_count;
 static int i8254_real_max_count;
 
+static int lapic_allclocks;
+TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
+
 struct mtx clock_lock;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
@@ -478,8 +481,22 @@ startrtclock()
 void
 cpu_initclocks()
 {
+	enum lapic_clock tlsca;
+	int tasc;
+
+	/* Initialize RTC. */
+	atrtc_start();
+	tasc = atrtc_setup_clock();
+
+	/*
+	 * If the atrtc successfully initialized and the users didn't force
+	 * otherwise use the LAPIC in order to cater hardclock only, otherwise
+	 * take in charge all the clock sources.
+	 */
+	tlsca = (lapic_allclocks == 0 && tasc != 0) ? LAPIC_CLOCK_HARDCLOCK :
+	    LAPIC_CLOCK_ALL;
+	using_lapic_timer = lapic_setup_clock(tlsca);
 
-	using_lapic_timer = lapic_setup_clock();
 	/*
 	 * If we aren't using the local APIC timer to drive the kernel
 	 * clocks, setup the interrupt handler for the 8254 timer 0 so
@@ -500,9 +517,6 @@ cpu_initclocks()
 		set_i8254_freq(i8254_freq, hz);
 	}
 
-	/* Initialize RTC. */
-	atrtc_start();
-
 	/*
 	 * If the separate statistics clock hasn't been explicility disabled
 	 * and we aren't already using the local APIC timer to drive the
@@ -510,7 +524,7 @@ cpu_initclocks()
 	 * drive statclock() and profclock().
 	 */
 	if (using_lapic_timer != LAPIC_CLOCK_ALL) {
-		using_atrtc_timer = atrtc_setup_clock();
+		using_atrtc_timer = tasc; 
 		if (using_atrtc_timer) {
 			/* Enable periodic interrupts from the RTC. */
 			intr_add_handler("rtc", 8,

Modified: stable/8/sys/i386/i386/local_apic.c
==============================================================================
--- stable/8/sys/i386/i386/local_apic.c	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/i386/i386/local_apic.c	Tue Mar 30 11:19:29 2010	(r205875)
@@ -150,6 +150,7 @@ extern inthand_t IDTVEC(rsvd);
 volatile lapic_t *lapic;
 vm_paddr_t lapic_paddr;
 static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
+static enum lapic_clock clockcoverage;
 
 static void	lapic_enable(void);
 static void	lapic_resume(struct pic *pic);
@@ -161,17 +162,6 @@ static uint32_t	lvt_mode(struct lapic *l
 
 struct pic lapic_pic = { .pic_resume = lapic_resume };
 
-/*
- * The atrtc device is compiled in only if atpic is present.
- * If it is not, force lapic to take care of all the clocks.
- */
-#ifdef DEV_ATPIC
-static int lapic_allclocks;
-TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
-#else
-static int lapic_allclocks = 1;
-#endif
-
 static uint32_t
 lvt_mode(struct lapic *la, u_int pin, uint32_t value)
 {
@@ -431,17 +421,20 @@ lapic_disable_pmc(void)
  * that it can drive hardclock, statclock, and profclock. 
  */
 enum lapic_clock
-lapic_setup_clock(void)
+lapic_setup_clock(enum lapic_clock srcsdes)
 {
 	u_long value;
 	int i;
 
-	/* Can't drive the timer without a local APIC. */
-	if (lapic == NULL)
-		return (LAPIC_CLOCK_NONE);
+	/* lapic_setup_clock() should not be called with LAPIC_CLOCK_NONE. */
+	MPASS(srcsdes != LAPIC_CLOCK_NONE);
 
-	if (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)
-		return (LAPIC_CLOCK_NONE);
+	/* Can't drive the timer without a local APIC. */
+	if (lapic == NULL ||
+	    (resource_int_value("apic", 0, "clock", &i) == 0 && i == 0)) {
+		clockcoverage = LAPIC_CLOCK_NONE;
+		return (clockcoverage);
+	}
 
 	/* Start off with a divisor of 2 (power on reset default). */
 	lapic_timer_divisor = 2;
@@ -477,7 +470,7 @@ lapic_setup_clock(void)
 	 * Please note that stathz and profhz are set only if all the
 	 * clocks are handled through the local APIC.
 	 */
-	if (lapic_allclocks != 0) {
+	if (srcsdes == LAPIC_CLOCK_ALL) {
 		if (hz >= 1500)
 			lapic_timer_hz = hz;
 		else if (hz >= 750)
@@ -487,7 +480,7 @@ lapic_setup_clock(void)
 	} else
 		lapic_timer_hz = hz;
 	lapic_timer_period = value / lapic_timer_hz;
-	if (lapic_allclocks != 0) {
+	if (srcsdes == LAPIC_CLOCK_ALL) {
 		if (lapic_timer_hz < 128)
 			stathz = lapic_timer_hz;
 		else
@@ -501,7 +494,8 @@ lapic_setup_clock(void)
 	 */
 	lapic_timer_periodic(lapic_timer_period);
 	lapic_timer_enable_intr();
-	return (lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL);
+	clockcoverage = srcsdes;
+	return (srcsdes);
 }
 
 void
@@ -804,7 +798,7 @@ lapic_handle_timer(struct trapframe *fra
 		else
 			hardclock_cpu(TRAPF_USERMODE(frame));
 	}
-	if (lapic_allclocks != 0) {
+	if (clockcoverage == LAPIC_CLOCK_ALL) {
 
 		/* Fire statclock at stathz. */
 		la->la_stat_ticks += stathz;

Modified: stable/8/sys/i386/include/apicvar.h
==============================================================================
--- stable/8/sys/i386/include/apicvar.h	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/i386/include/apicvar.h	Tue Mar 30 11:19:29 2010	(r205875)
@@ -259,7 +259,7 @@ int	lapic_set_lvt_triggermode(u_int apic
 	    enum intr_trigger trigger);
 void	lapic_set_tpr(u_int vector);
 void	lapic_setup(int boot);
-enum lapic_clock	lapic_setup_clock(void);
+enum lapic_clock	lapic_setup_clock(enum lapic_clock srcsdes);
 
 #endif /* !LOCORE */
 #endif /* _MACHINE_APICVAR_H_ */

Modified: stable/8/sys/i386/isa/clock.c
==============================================================================
--- stable/8/sys/i386/isa/clock.c	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/i386/isa/clock.c	Tue Mar 30 11:19:29 2010	(r205875)
@@ -97,6 +97,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq
 int	i8254_max_count;
 static int i8254_real_max_count;
 
+static int lapic_allclocks;
+TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
+
 struct mtx clock_lock;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
@@ -522,9 +525,24 @@ startrtclock()
 void
 cpu_initclocks()
 {
+#ifdef DEV_APIC
+	enum lapic_clock tlsca;
+#endif
+	int tasc;
+
+	/* Initialize RTC. */
+	atrtc_start();
+	tasc = atrtc_setup_clock();
 
+	/*
+	 * If the atrtc successfully initialized and the users didn't force
+	 * otherwise use the LAPIC in order to cater hardclock only, otherwise
+	 * take in charge all the clock sources.
+	 */
 #ifdef DEV_APIC
-	using_lapic_timer = lapic_setup_clock();
+	tlsca = (lapic_allclocks == 0 && tasc != 0) ? LAPIC_CLOCK_HARDCLOCK :
+	    LAPIC_CLOCK_ALL;
+	using_lapic_timer = lapic_setup_clock(tlsca);
 #endif
 	/*
 	 * If we aren't using the local APIC timer to drive the kernel
@@ -546,9 +564,6 @@ cpu_initclocks()
 		set_i8254_freq(i8254_freq, hz);
 	}
 
-	/* Initialize RTC. */
-	atrtc_start();
-
 	/*
 	 * If the separate statistics clock hasn't been explicility disabled
 	 * and we aren't already using the local APIC timer to drive the
@@ -556,7 +571,7 @@ cpu_initclocks()
 	 * drive statclock() and profclock().
 	 */
 	if (using_lapic_timer != LAPIC_CLOCK_ALL) {
-		using_atrtc_timer = atrtc_setup_clock();
+		using_atrtc_timer = tasc; 
 		if (using_atrtc_timer) {
 			/* Enable periodic interrupts from the RTC. */
 			intr_add_handler("rtc", 8,

Modified: stable/8/sys/pc98/cbus/clock.c
==============================================================================
--- stable/8/sys/pc98/cbus/clock.c	Tue Mar 30 09:58:21 2010	(r205874)
+++ stable/8/sys/pc98/cbus/clock.c	Tue Mar 30 11:19:29 2010	(r205875)
@@ -93,6 +93,9 @@ TUNABLE_INT("hw.i8254.freq", &i8254_freq
 int	i8254_max_count;
 static int i8254_real_max_count;
 
+static int lapic_allclocks;
+TUNABLE_INT("machdep.lapic_allclocks", &lapic_allclocks);
+
 static	struct mtx clock_lock;
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
@@ -432,9 +435,11 @@ startrtclock()
 void
 cpu_initclocks()
 {
+#if defined(DEV_APIC)
+	enum lapic_clock tlsca;
 
-#ifdef DEV_APIC
-	using_lapic_timer = lapic_setup_clock();
+	tlsca = lapic_allclocks == 0 ? LAPIC_CLOCK_HARDCLOCK : LAPIC_CLOCK_ALL;
+	using_lapic_timer = lapic_setup_clock(tlsca);
 #endif
 	/*
 	 * If we aren't using the local APIC timer to drive the kernel


More information about the svn-src-all mailing list