* [PATCH] Prevent decrementer clockevents from firing early
@ 2007-10-08 23:59 Paul Mackerras
2007-10-09 0:34 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 2+ messages in thread
From: Paul Mackerras @ 2007-10-08 23:59 UTC (permalink / raw)
To: linuxppc-dev
On old powermacs, we sometimes set the decrementer to 1 in order to
trigger a decrementer interrupt, which we use to handle an interrupt
that was pending at the time when it was re-enabled. This was causing
the decrementer clock event device to call the event function for the
next event early, which was causing problems when high-res timers were
not enabled.
This fixes the problem by recording the timebase value at which the
next event should occur, and checking the current timebase against the
recorded value in timer_interrupt. If it isn't time for the next
event, it just reprograms the decrementer and returns.
This also subtracts 1 from the value stored into the decrementer,
which is appropriate because the decrementer interrupts on the
transition from 0 to -1, not when the decrementer reaches 0.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index d20947c..1481e6f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -118,6 +118,7 @@ static struct clock_event_device decrementer_clockevent = {
static DEFINE_PER_CPU(struct clock_event_device, decrementers);
void init_decrementer_clockevent(void);
+static DEFINE_PER_CPU(u64, decrementer_next_tb);
#ifdef CONFIG_PPC_ISERIES
static unsigned long __initdata iSeries_recal_titan;
@@ -541,6 +542,7 @@ 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);
+ u64 now;
/* Ensure a positive value is written to the decrementer, or else
* some CPUs will continuue to take decrementer exceptions */
@@ -551,6 +553,14 @@ void timer_interrupt(struct pt_regs * regs)
do_IRQ(regs);
#endif
+ now = get_tb();
+ if (now < per_cpu(decrementer_next_tb, cpu)) {
+ /* not time for this event yet */
+ now = per_cpu(decrementer_next_tb, cpu) - now;
+ if (now <= DECREMENTER_MAX)
+ set_dec((unsigned int)now - 1);
+ return;
+ }
old_regs = set_irq_regs(regs);
irq_enter();
@@ -797,6 +807,10 @@ 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() + evt;
+ /* The decrementer interrupts on the 0 -> -1 transition */
+ if (evt)
+ --evt;
set_dec(evt);
return 0;
}
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Prevent decrementer clockevents from firing early
2007-10-08 23:59 [PATCH] Prevent decrementer clockevents from firing early Paul Mackerras
@ 2007-10-09 0:34 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 2+ messages in thread
From: Benjamin Herrenschmidt @ 2007-10-09 0:34 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
On Tue, 2007-10-09 at 09:59 +1000, Paul Mackerras wrote:
> On old powermacs, we sometimes set the decrementer to 1 in order to
> trigger a decrementer interrupt, which we use to handle an interrupt
> that was pending at the time when it was re-enabled. This was causing
> the decrementer clock event device to call the event function for the
> next event early, which was causing problems when high-res timers were
> not enabled.
>
> This fixes the problem by recording the timebase value at which the
> next event should occur, and checking the current timebase against the
> recorded value in timer_interrupt. If it isn't time for the next
> event, it just reprograms the decrementer and returns.
>
> This also subtracts 1 from the value stored into the decrementer,
> which is appropriate because the decrementer interrupts on the
> transition from 0 to -1, not when the decrementer reaches 0.
>
> Signed-off-by: Paul Mackerras <paulus@samba.org>
> ---
Do we also need to handle lost ticks ? That is loop & do multiple events
like we used to do with the previous implementation ?
Cheers,
Ben.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-10-09 0:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-08 23:59 [PATCH] Prevent decrementer clockevents from firing early Paul Mackerras
2007-10-09 0:34 ` Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).