cvs commit: src/sys/kern sched_ule.c

John Baldwin jhb at freebsd.org
Tue Oct 2 11:53:50 PDT 2007


On Tuesday 02 October 2007 09:49:34 am Bruce Evans wrote:
> Apparently, there is a scaling bug for hz or extra interrupts for
> the larger hz help, and the default preempt_thresh is not best.

-current on i386 and amd64 does a very poor job of scaling stathz and profhz 
with hz, so this may explain problems at hz=100.  I have an attempt to make 
stathz and profhz more sane while also trying to not always drive the lapic 
timer at hz * 2.  I used to have a test program that would display all the 
frequencies for different 'hz' values but have misplaced it. :(

--- //depot/vendor/freebsd/src/sys/amd64/amd64/local_apic.c	2007/09/11 
22:57:37
+++ //depot/user/jhb/acpipci/amd64/amd64/local_apic.c	2007/09/24 17:24:13
@@ -72,8 +72,6 @@
 CTASSERT(IPI_STOP < APIC_SPURIOUS_INT);
 
 #define	LAPIC_TIMER_HZ_DIVIDER		2
-#define	LAPIC_TIMER_STATHZ_DIVIDER	15
-#define	LAPIC_TIMER_PROFHZ_DIVIDER	3
 
 /* Magic IRQ values for the timer and syscalls. */
 #define	IRQ_TIMER	(NUM_IO_INTS + 1)
@@ -383,13 +381,24 @@
 		    lapic_timer_divisor, value);
 
 	/*
-	 * We will drive the timer at a small multiple of hz and drive
-	 * both of the other timers with similarly small but relatively
-	 * prime divisors.
+	 * We want to run stathz in the neighborhood of 128hz.  We would
+	 * like profhz to run as often as possible, so we let it run on
+	 * each clock tick.  We try to honor the requested 'hz' value as
+	 * much as possible.
+	 *
+	 * If 'hz' is above 1500, then we just let the lapic timer
+	 * (and profhz) run at hz.  If 'hz' is below 1500 but above
+	 * 750, then we let the lapic timer run at 2 * 'hz'.  If 'hz'
+	 * is below 750 then we let the lapic timer run at 4 * 'hz'.
 	 */
-	lapic_timer_hz = hz * LAPIC_TIMER_HZ_DIVIDER;
-	stathz = lapic_timer_hz / LAPIC_TIMER_STATHZ_DIVIDER;
-	profhz = lapic_timer_hz / LAPIC_TIMER_PROFHZ_DIVIDER;
+	if (hz >= 1500)
+		lapic_timer_hz = hz;
+	else if (hz >= 750)
+		lapic_timer_hz = hz * 2;
+	else
+		lapic_timer_hz = hz * 4;
+	stathz = lapic_timer_hz / (lapic_timer_hz * 128);
+	profhz = lapic_timer_hz;
 	lapic_timer_period = value / lapic_timer_hz;
 
 	/*
--- //depot/vendor/freebsd/src/sys/i386/i386/local_apic.c	2007/09/11 22:57:37
+++ //depot/user/jhb/acpipci/i386/i386/local_apic.c	2007/09/24 17:24:13
@@ -72,8 +72,6 @@
 CTASSERT(IPI_STOP < APIC_SPURIOUS_INT);
 
 #define	LAPIC_TIMER_HZ_DIVIDER		2
-#define	LAPIC_TIMER_STATHZ_DIVIDER	15
-#define	LAPIC_TIMER_PROFHZ_DIVIDER	3
 
 /* Magic IRQ values for the timer and syscalls. */
 #define	IRQ_TIMER	(NUM_IO_INTS + 1)
@@ -385,13 +383,24 @@
 		    lapic_timer_divisor, value);
 
 	/*
-	 * We will drive the timer at a small multiple of hz and drive
-	 * both of the other timers with similarly small but relatively
-	 * prime divisors.
+	 * We want to run stathz in the neighborhood of 128hz.  We would
+	 * like profhz to run as often as possible, so we let it run on
+	 * each clock tick.  We try to honor the requested 'hz' value as
+	 * much as possible.
+	 *
+	 * If 'hz' is above 1500, then we just let the lapic timer
+	 * (and profhz) run at hz.  If 'hz' is below 1500 but above
+	 * 750, then we let the lapic timer run at 2 * 'hz'.  If 'hz'
+	 * is below 750 then we let the lapic timer run at 4 * 'hz'.
 	 */
-	lapic_timer_hz = hz * LAPIC_TIMER_HZ_DIVIDER;
-	stathz = lapic_timer_hz / LAPIC_TIMER_STATHZ_DIVIDER;
-	profhz = lapic_timer_hz / LAPIC_TIMER_PROFHZ_DIVIDER;
+	if (hz >= 1500)
+		lapic_timer_hz = hz;
+	else if (hz >= 750)
+		lapic_timer_hz = hz * 2;
+	else
+		lapic_timer_hz = hz * 4;
+	stathz = lapic_timer_hz / (lapic_timer_hz * 128);
+	profhz = lapic_timer_hz;
 	lapic_timer_period = value / lapic_timer_hz;
 
 	/*

-- 
John Baldwin


More information about the cvs-src mailing list