mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
[PATCH] high-res timers: resume fix
Soeren Sonnenburg reported that upon resume he is getting this backtrace: [<c0119637>] smp_apic_timer_interrupt+0x57/0x90 [<c0142d30>] retrigger_next_event+0x0/0xb0 [<c0104d30>] apic_timer_interrupt+0x28/0x30 [<c0142d30>] retrigger_next_event+0x0/0xb0 [<c0140068>] __kfifo_put+0x8/0x90 [<c0130fe5>] on_each_cpu+0x35/0x60 [<c0143538>] clock_was_set+0x18/0x20 [<c0135cdc>] timekeeping_resume+0x7c/0xa0 [<c02aabe1>] __sysdev_resume+0x11/0x80 [<c02ab0c7>] sysdev_resume+0x47/0x80 [<c02b0b05>] device_power_up+0x5/0x10 it turns out that on resume we mistakenly re-enable interrupts too early. Do the timer retrigger only on the current CPU. Signed-off-by: Ingo Molnar <mingo@elte.hu> Acked-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Soeren Sonnenburg <kernel@nn7.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
bbef618190
commit
995f054f2a
3 changed files with 16 additions and 1 deletions
|
@ -206,6 +206,7 @@ struct hrtimer_cpu_base {
|
|||
struct clock_event_device;
|
||||
|
||||
extern void clock_was_set(void);
|
||||
extern void hres_timers_resume(void);
|
||||
extern void hrtimer_interrupt(struct clock_event_device *dev);
|
||||
|
||||
/*
|
||||
|
@ -236,6 +237,8 @@ static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
|
|||
*/
|
||||
static inline void clock_was_set(void) { }
|
||||
|
||||
static inline void hres_timers_resume(void) { }
|
||||
|
||||
/*
|
||||
* In non high resolution mode the time reference is taken from
|
||||
* the base softirq time variable.
|
||||
|
|
|
@ -458,6 +458,18 @@ void clock_was_set(void)
|
|||
on_each_cpu(retrigger_next_event, NULL, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* During resume we might have to reprogram the high resolution timer
|
||||
* interrupt (on the local CPU):
|
||||
*/
|
||||
void hres_timers_resume(void)
|
||||
{
|
||||
WARN_ON_ONCE(num_online_cpus() > 1);
|
||||
|
||||
/* Retrigger the CPU local events: */
|
||||
retrigger_next_event(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check, whether the timer is on the callback pending list
|
||||
*/
|
||||
|
|
|
@ -1016,7 +1016,7 @@ static int timekeeping_resume(struct sys_device *dev)
|
|||
clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
|
||||
|
||||
/* Resume hrtimers */
|
||||
clock_was_set();
|
||||
hres_timers_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue