Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Oct 2007 14:43:38 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        src-committers@freebsd.org, cvs-src@freebsd.org, Jeff Roberson <jeff@freebsd.org>, Garance A Drosehn <gad@freebsd.org>, Ben Kaduk <minimarmot@gmail.com>, cvs-all@freebsd.org, Jeff Roberson <jroberson@chesapeake.net>
Subject:   Re: cvs commit: src/sys/kern sched_ule.c
Message-ID:  <200710021443.40264.jhb@freebsd.org>
In-Reply-To: <20071002213829.F12287@delplex.bde.org>
References:  <20071001145257.EC9FC4500F@ptavv.es.net> <20071001232743.Q539@10.0.0.1> <20071002213829.F12287@delplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



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