diff options
author | jhb <jhb@FreeBSD.org> | 2008-08-23 12:35:43 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2008-08-23 12:35:43 +0000 |
commit | 346004ece8d109a52c6986565142b0ab8cb7df0d (patch) | |
tree | 7f56646d08efaa5227be59baff72d3bb321d15f2 /sys/amd64 | |
parent | 9c1b35c579df4fc03db919b805e2dbb5dc3c540f (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/local_apic.c | 27 |
1 files changed, 17 insertions, 10 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; /* |