|
@@ -475,6 +475,7 @@ void timer_interrupt(struct pt_regs * regs)
|
|
|
struct pt_regs *old_regs;
|
|
|
u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
|
|
|
struct clock_event_device *evt = &__get_cpu_var(decrementers);
|
|
|
+ u64 now;
|
|
|
|
|
|
/* Ensure a positive value is written to the decrementer, or else
|
|
|
* some CPUs will continue to take decrementer exceptions.
|
|
@@ -509,9 +510,16 @@ void timer_interrupt(struct pt_regs * regs)
|
|
|
irq_work_run();
|
|
|
}
|
|
|
|
|
|
- *next_tb = ~(u64)0;
|
|
|
- if (evt->event_handler)
|
|
|
- evt->event_handler(evt);
|
|
|
+ now = get_tb_or_rtc();
|
|
|
+ if (now >= *next_tb) {
|
|
|
+ *next_tb = ~(u64)0;
|
|
|
+ if (evt->event_handler)
|
|
|
+ evt->event_handler(evt);
|
|
|
+ } else {
|
|
|
+ now = *next_tb - now;
|
|
|
+ if (now <= DECREMENTER_MAX)
|
|
|
+ set_dec((int)now);
|
|
|
+ }
|
|
|
|
|
|
#ifdef CONFIG_PPC64
|
|
|
/* collect purr register values often, for accurate calculations */
|