summaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/time.c36
1 files changed, 13 insertions, 23 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 733e0e3324b8..ed9fc3d057a6 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -171,39 +171,29 @@ void vtime_account_hardirq(struct task_struct *tsk)
static irqreturn_t
timer_interrupt (int irq, void *dev_id)
{
- unsigned long new_itm;
+ unsigned long cur_itm, new_itm, ticks;
if (cpu_is_offline(smp_processor_id())) {
return IRQ_HANDLED;
}
new_itm = local_cpu_data->itm_next;
+ cur_itm = ia64_get_itc();
- if (!time_after(ia64_get_itc(), new_itm))
+ if (!time_after(cur_itm, new_itm)) {
printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
- ia64_get_itc(), new_itm);
-
- profile_tick(CPU_PROFILING);
-
- while (1) {
- update_process_times(user_mode(get_irq_regs()));
-
- new_itm += local_cpu_data->itm_delta;
-
- if (smp_processor_id() == time_keeper_id)
- xtime_update(1);
-
- local_cpu_data->itm_next = new_itm;
+ cur_itm, new_itm);
+ ticks = 1;
+ } else {
+ ticks = DIV_ROUND_UP(cur_itm - new_itm,
+ local_cpu_data->itm_delta);
+ new_itm += ticks * local_cpu_data->itm_delta;
+ }
- if (time_after(new_itm, ia64_get_itc()))
- break;
+ if (smp_processor_id() != time_keeper_id)
+ ticks = 0;
- /*
- * Allow IPIs to interrupt the timer loop.
- */
- local_irq_enable();
- local_irq_disable();
- }
+ legacy_timer_tick(ticks);
do {
/*