summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-08-23 12:35:43 +0000
committerjhb <jhb@FreeBSD.org>2008-08-23 12:35:43 +0000
commit346004ece8d109a52c6986565142b0ab8cb7df0d (patch)
tree7f56646d08efaa5227be59baff72d3bb321d15f2
parent9c1b35c579df4fc03db919b805e2dbb5dc3c540f (diff)
downloadFreeBSD-src-346004ece8d109a52c6986565142b0ab8cb7df0d.zip
FreeBSD-src-346004ece8d109a52c6986565142b0ab8cb7df0d.tar.gz
Adjust the handling the various timer frequencies when using the lapic
timer. Previously, the various divisors were fixed which meant that while it gave somewhat reasonable stathz, etc. at hz=1000, it went off the rails with any other hz value. With these changes, we now pick a lapic timer hz based on the value of hz. If hz is >= 1500, then the lapic timer runs at hz. If 1500 hz >= 750, we run the lapic timer at hz * 2. If hz < 750, we run at hz * 4. We compute a divider at runtime to make stathz run as close to 128 as we can since stathz really wants to be run at something close to that frequency. Profiling just runs on every clock tick. So some examples: With hz = 100, the lapic timer now runs at 400 instead of 2000. stathz will be 133, and profhz = 400. With hz = 1000 (default), the lapic timer is still at 2000 (as it is now), stathz is at 133 (as it is now), and profhz will be 2000 (previously 666). MFC after: 2 weeks
-rw-r--r--sys/amd64/amd64/local_apic.c27
-rw-r--r--sys/i386/i386/local_apic.c27
2 files changed, 34 insertions, 20 deletions
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 47bb78d..7f31e1c 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -77,10 +77,6 @@ CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
CTASSERT(APIC_LOCAL_INTS == 240);
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)
#define IRQ_SYSCALL (NUM_IO_INTS + 2)
@@ -389,13 +385,24 @@ lapic_setup_clock(void)
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;
/*
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index ffdcdf6..664b186 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -77,10 +77,6 @@ CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
CTASSERT(APIC_LOCAL_INTS == 240);
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)
#define IRQ_SYSCALL (NUM_IO_INTS + 2)
@@ -391,13 +387,24 @@ lapic_setup_clock(void)
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;
/*
OpenPOWER on IntegriCloud