Skip to content

Commit 796130b

Browse files
committed
ia64: fix timer cleanup regression
A cleanup patch from my legacy timer series broke ia64 and led to RCU stall errors and a fast system clock: [ 909.360108] INFO: task systemd-sysv-ge:200 blocked for more than 127 seconds. [ 909.360108] Not tainted 5.10.0+ #130 [ 909.360108] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 909.360108] task:systemd-sysv-ge state:D stack: 0 pid: 200 ppid: 189 flags:0x00000000 [ 909.364108] [ 909.364108] Call Trace: [ 909.364423] [<a00000010109b210>] __schedule+0x890/0x21e0 [ 909.364423] sp=e0000100487d7b70 bsp=e0000100487d1748 [ 909.368423] [<a00000010109cc00>] schedule+0xa0/0x240 [ 909.368423] sp=e0000100487d7b90 bsp=e0000100487d16e0 [ 909.368558] [<a00000010109ce70>] io_schedule+0x70/0xa0 [ 909.368558] sp=e0000100487d7b90 bsp=e0000100487d16c0 [ 909.372290] [<a00000010109e1c0>] bit_wait_io+0x20/0xe0 [ 909.372290] sp=e0000100487d7b90 bsp=e0000100487d1698 [ 909.374168] rcu: INFO: rcu_sched detected stalls on CPUs/tasks: [ 909.376290] [<a00000010109d860>] __wait_on_bit+0xc0/0x1c0 [ 909.376290] sp=e0000100487d7b90 bsp=e0000100487d1648 [ 909.374168] rcu: 3-....: (2 ticks this GP) idle=19e/1/0x4000000000000002 softirq=1581/1581 fqs=2 [ 909.374168] (detected by 0, t=5661 jiffies, g=1089, q=3) [ 909.376290] [<a00000010109da80>] out_of_line_wait_on_bit+0x120/0x140 [ 909.376290] sp=e0000100487d7b90 bsp=e0000100487d1610 [ 909.374168] Task dump for CPU 3: [ 909.374168] task:khungtaskd state:R running task Revert most of my patch to make this work again, including the extra update_process_times()/profile_tick() and the local_irq_enable() in the loop that I expected not to be needed here. I have not found out exactly what goes wrong, and would suggest that someone with hardware access tries to convert this code into a singleshot clockevent driver, which should give better behavior in all cases. Reported-by: John Paul Adrian Glaubitz <[email protected]> Fixes: 2b49ddc ("ia64: convert to legacy_timer_tick") Cc: John Stultz <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: Frederic Weisbecker <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent 5c8fe58 commit 796130b

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

arch/ia64/kernel/time.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -171,29 +171,34 @@ void vtime_account_hardirq(struct task_struct *tsk)
171171
static irqreturn_t
172172
timer_interrupt (int irq, void *dev_id)
173173
{
174-
unsigned long cur_itm, new_itm, ticks;
174+
unsigned long new_itm;
175175

176176
if (cpu_is_offline(smp_processor_id())) {
177177
return IRQ_HANDLED;
178178
}
179179

180180
new_itm = local_cpu_data->itm_next;
181-
cur_itm = ia64_get_itc();
182181

183-
if (!time_after(cur_itm, new_itm)) {
182+
if (!time_after(ia64_get_itc(), new_itm))
184183
printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
185-
cur_itm, new_itm);
186-
ticks = 1;
187-
} else {
188-
ticks = DIV_ROUND_UP(cur_itm - new_itm,
189-
local_cpu_data->itm_delta);
190-
new_itm += ticks * local_cpu_data->itm_delta;
191-
}
184+
ia64_get_itc(), new_itm);
185+
186+
while (1) {
187+
new_itm += local_cpu_data->itm_delta;
188+
189+
legacy_timer_tick(smp_processor_id() == time_keeper_id);
192190

193-
if (smp_processor_id() != time_keeper_id)
194-
ticks = 0;
191+
local_cpu_data->itm_next = new_itm;
195192

196-
legacy_timer_tick(ticks);
193+
if (time_after(new_itm, ia64_get_itc()))
194+
break;
195+
196+
/*
197+
* Allow IPIs to interrupt the timer loop.
198+
*/
199+
local_irq_enable();
200+
local_irq_disable();
201+
}
197202

198203
do {
199204
/*

0 commit comments

Comments
 (0)