Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ia64: convert to legacy_timer_tick

ia64 is the only architecture that calls xtime_update() in a loop,
once for each jiffie that has passed since the last event.

Before commit 3171a0305d62 ("[PATCH] simplify update_times (avoid
jiffies/jiffies_64 aliasing problem)") in 2006, it could not actually do
this any differently, but now it seems simpler to just pass the number
of jiffies that passed in the meantime.

While this loses the ability process interrupts in the middle of
the timer tick by calling local_irq_enable(), doing so is fairly
peculiar anyway and it seems better to just do what everyone
else does here.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+15 -24
+1
arch/ia64/Kconfig
··· 46 46 select ARCH_THREAD_STACK_ALLOCATOR 47 47 select ARCH_CLOCKSOURCE_DATA 48 48 select GENERIC_TIME_VSYSCALL 49 + select LEGACY_TIMER_TICK 49 50 select SWIOTLB 50 51 select SYSCTL_ARCH_UNALIGN_NO_WARN 51 52 select HAVE_MOD_ARCH_SPECIFIC
+14 -24
arch/ia64/kernel/time.c
··· 161 161 static irqreturn_t 162 162 timer_interrupt (int irq, void *dev_id) 163 163 { 164 - unsigned long new_itm; 164 + unsigned long cur_itm, new_itm, ticks; 165 165 166 166 if (cpu_is_offline(smp_processor_id())) { 167 167 return IRQ_HANDLED; 168 168 } 169 169 170 170 new_itm = local_cpu_data->itm_next; 171 + cur_itm = ia64_get_itc(); 171 172 172 - if (!time_after(ia64_get_itc(), new_itm)) 173 + if (!time_after(cur_itm, new_itm)) { 173 174 printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", 174 - ia64_get_itc(), new_itm); 175 - 176 - profile_tick(CPU_PROFILING); 177 - 178 - while (1) { 179 - update_process_times(user_mode(get_irq_regs())); 180 - 181 - new_itm += local_cpu_data->itm_delta; 182 - 183 - if (smp_processor_id() == time_keeper_id) 184 - xtime_update(1); 185 - 186 - local_cpu_data->itm_next = new_itm; 187 - 188 - if (time_after(new_itm, ia64_get_itc())) 189 - break; 190 - 191 - /* 192 - * Allow IPIs to interrupt the timer loop. 193 - */ 194 - local_irq_enable(); 195 - local_irq_disable(); 175 + cur_itm, new_itm); 176 + ticks = 1; 177 + } else { 178 + ticks = DIV_ROUND_UP(cur_itm - new_itm, 179 + local_cpu_data->itm_delta); 180 + new_itm += ticks * local_cpu_data->itm_delta; 196 181 } 182 + 183 + if (smp_processor_id() != time_keeper_id) 184 + ticks = 0; 185 + 186 + legacy_timer_tick(ticks); 197 187 198 188 do { 199 189 /*