diff options
author | mav <mav@FreeBSD.org> | 2009-05-03 17:47:21 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-05-03 17:47:21 +0000 |
commit | 98565a1214eb4106f0a1b76ff6696b9980497195 (patch) | |
tree | ce5adc34e083eefdd76b28a61134b800569d7b6e /sys/amd64 | |
parent | 77cd1e9862e8b7f432feb7272c92e04d5b0f47fd (diff) | |
download | FreeBSD-src-98565a1214eb4106f0a1b76ff6696b9980497195.zip FreeBSD-src-98565a1214eb4106f0a1b76ff6696b9980497195.tar.gz |
Rename statclock_disable variable to atrtcclock_disable that it actually is,
and hide it inside of atrtc driver. Add new tunable hint.atrtc.0.clock
controlling it. Setting it to 0 disables using RTC clock as stat-/
profclock sources.
Teach i386 and amd64 SMP platforms to emulate stat-/profclocks using i8254
hardclock, when LAPIC and RTC clocks are disabled.
This allows to reduce global interrupt rate of idle system down to about
100 interrupts per core, permitting C3 and deeper C-states provide maximum
CPU power efficiency.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/include/clock.h | 1 | ||||
-rw-r--r-- | sys/amd64/isa/clock.c | 36 |
2 files changed, 15 insertions, 22 deletions
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index 155fdd1..8af699e 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -15,7 +15,6 @@ * XXX large parts of the driver and its interface are misplaced. */ extern int clkintr_pending; -extern int statclock_disable; extern u_int i8254_freq; extern int i8254_max_count; extern uint64_t tsc_freq; diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index b526025..129350b2 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -76,7 +76,6 @@ __FBSDID("$FreeBSD$"); int clkintr_pending; static int pscnt = 1; static int psdiv = 1; -int statclock_disable; #ifndef TIMER_FREQ #define TIMER_FREQ 1193182 #endif @@ -91,6 +90,7 @@ static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; static int (*i8254_pending)(struct intsrc *); static int i8254_ticked; +static int using_atrtc_timer; static int using_lapic_timer; /* Values for timerX_state: */ @@ -122,6 +122,8 @@ hardclockintr(struct trapframe *frame) hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); else hardclock_cpu(TRAPF_USERMODE(frame)); + if (!using_atrtc_timer) + statclockintr(frame); return (FILTER_HANDLED); } @@ -163,10 +165,7 @@ clkintr(struct trapframe *frame) if (smp_started) ipi_all_but_self(IPI_HARDCLOCK); #endif - if (PCPU_GET(cpuid) == 0) - hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); - else - hardclock_cpu(TRAPF_USERMODE(frame)); + hardclockintr(frame); return (FILTER_HANDLED); } @@ -461,7 +460,6 @@ startrtclock() void cpu_initclocks() { - int diag; using_lapic_timer = lapic_setup_clock(); /* @@ -493,21 +491,17 @@ cpu_initclocks() * kernel clocks, then setup the RTC to periodically interrupt to * drive statclock() and profclock(). */ - if (!statclock_disable && !using_lapic_timer) { - diag = rtcin(RTC_DIAG); - if (diag != 0) - printf("RTC BIOS diagnostic error %b\n", - diag, RTCDG_BITS); - - /* Setting stathz to nonzero early helps avoid races. */ - stathz = RTC_NOPROFRATE; - profhz = RTC_PROFRATE; - - /* Enable periodic interrupts from the RTC. */ - intr_add_handler("rtc", 8, - (driver_filter_t *)rtcintr, NULL, NULL, - INTR_TYPE_CLK, NULL); - atrtc_enable_intr(); + if (!using_lapic_timer) { + using_atrtc_timer = atrtc_setup_clock(); + if (using_atrtc_timer) { + /* Enable periodic interrupts from the RTC. */ + intr_add_handler("rtc", 8, + (driver_filter_t *)rtcintr, NULL, NULL, + INTR_TYPE_CLK, NULL); + atrtc_enable_intr(); + } else { + profhz = stathz = hz; + } } init_TSC_tc(); |