diff options
author | Milton Miller <miltonm@bga.com> | 2007-12-14 15:52:15 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-12-20 16:15:41 +1100 |
commit | 6e6b44e8223a01d35fceec3631be356fbdbcf004 (patch) | |
tree | dab1e44a25802a2119e3ab1bdb855598640a1eda /arch/powerpc/kernel/time.c | |
parent | 8b5621f183f7e56958b0a0aae689af5af2efeda7 (diff) |
[POWERPC] Timer interrupt: use a struct for two per_cpu varables
timer_interrupt() was calculating per_cpu_offset several times, having to
start from the toc because of potential aliasing issues.
Placing both decrementer per_cpu varables in a struct and calculating
the address once with __get_cpu_var results in better code on both 32
and 64 bit.
Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r-- | arch/powerpc/kernel/time.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 888c65726eb..5cf39408059 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -116,8 +116,12 @@ static struct clock_event_device decrementer_clockevent = { .features = CLOCK_EVT_FEAT_ONESHOT, }; -static DEFINE_PER_CPU(struct clock_event_device, decrementers); -static DEFINE_PER_CPU(u64, decrementer_next_tb); +struct decrementer_clock { + struct clock_event_device event; + u64 next_tb; +}; + +static DEFINE_PER_CPU(struct decrementer_clock, decrementers); #ifdef CONFIG_PPC_ISERIES static unsigned long __initdata iSeries_recal_titan; @@ -555,8 +559,8 @@ void __init iSeries_time_init_early(void) void timer_interrupt(struct pt_regs * regs) { struct pt_regs *old_regs; - int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(decrementers, cpu); + struct decrementer_clock *decrementer = &__get_cpu_var(decrementers); + struct clock_event_device *evt = &decrementer->event; u64 now; /* Ensure a positive value is written to the decrementer, or else @@ -569,9 +573,9 @@ void timer_interrupt(struct pt_regs * regs) #endif now = get_tb_or_rtc(); - if (now < per_cpu(decrementer_next_tb, cpu)) { + if (now < decrementer->next_tb) { /* not time for this event yet */ - now = per_cpu(decrementer_next_tb, cpu) - now; + now = decrementer->next_tb - now; if (now <= DECREMENTER_MAX) set_dec((int)now); return; @@ -810,7 +814,7 @@ void __init clocksource_init(void) static int decrementer_set_next_event(unsigned long evt, struct clock_event_device *dev) { - __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt; + __get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt; set_dec(evt); return 0; } @@ -824,7 +828,7 @@ static void decrementer_set_mode(enum clock_event_mode mode, static void register_decrementer_clockevent(int cpu) { - struct clock_event_device *dec = &per_cpu(decrementers, cpu); + struct clock_event_device *dec = &per_cpu(decrementers, cpu).event; *dec = decrementer_clockevent; dec->cpumask = cpumask_of_cpu(cpu); |