Skip to content

Commit 98facf0

Browse files
committed
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner: "This update brings along: - Two fixes for long standing bugs in the hrtimer code, one which prevents remote enqueuing and the other preventing arbitrary delays after a interrupt hang was detected - A fix in the timer wheel which prevents math overflow - A fix for a long standing issue with the architected ARM timer related to the C3STOP mechanism. - A trivial compile fix for nspire SoC clocksource" * 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: timer: Prevent overflow in apply_slack hrtimer: Prevent remote enqueue of leftmost timers hrtimer: Prevent all reprogramming if hang detected clocksource: nspire: Fix compiler warning clocksource: arch_arm_timer: Fix age-old arch timer C3STOP detection issue
2 parents 00622e6 + 98a01e7 commit 98facf0

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

Documentation/devicetree/bindings/arm/arch_timer.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ to deliver its interrupts via SPIs.
1919

2020
- clock-frequency : The frequency of the main counter, in Hz. Optional.
2121

22+
- always-on : a boolean property. If present, the timer is powered through an
23+
always-on power domain, therefore it never loses context.
24+
2225
Example:
2326

2427
timer {

drivers/clocksource/arm_arch_timer.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ static int arch_timer_ppi[MAX_TIMER_PPI];
6666
static struct clock_event_device __percpu *arch_timer_evt;
6767

6868
static bool arch_timer_use_virtual = true;
69+
static bool arch_timer_c3stop;
6970
static bool arch_timer_mem_use_virtual;
7071

7172
/*
@@ -263,7 +264,8 @@ static void __arch_timer_setup(unsigned type,
263264
clk->features = CLOCK_EVT_FEAT_ONESHOT;
264265

265266
if (type == ARCH_CP15_TIMER) {
266-
clk->features |= CLOCK_EVT_FEAT_C3STOP;
267+
if (arch_timer_c3stop)
268+
clk->features |= CLOCK_EVT_FEAT_C3STOP;
267269
clk->name = "arch_sys_timer";
268270
clk->rating = 450;
269271
clk->cpumask = cpumask_of(smp_processor_id());
@@ -665,6 +667,8 @@ static void __init arch_timer_init(struct device_node *np)
665667
}
666668
}
667669

670+
arch_timer_c3stop = !of_property_read_bool(np, "always-on");
671+
668672
arch_timer_register();
669673
arch_timer_common_init();
670674
}

drivers/clocksource/zevio-timer.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,9 @@ static int __init zevio_timer_add(struct device_node *node)
212212
return ret;
213213
}
214214

215-
CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_add);
215+
static void __init zevio_timer_init(struct device_node *node)
216+
{
217+
BUG_ON(zevio_timer_add(node));
218+
}
219+
220+
CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init);

kernel/hrtimer.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
234234
goto again;
235235
}
236236
timer->base = new_base;
237+
} else {
238+
if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
239+
cpu = this_cpu;
240+
goto again;
241+
}
237242
}
238243
return new_base;
239244
}
@@ -569,6 +574,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
569574

570575
cpu_base->expires_next.tv64 = expires_next.tv64;
571576

577+
/*
578+
* If a hang was detected in the last timer interrupt then we
579+
* leave the hang delay active in the hardware. We want the
580+
* system to make progress. That also prevents the following
581+
* scenario:
582+
* T1 expires 50ms from now
583+
* T2 expires 5s from now
584+
*
585+
* T1 is removed, so this code is called and would reprogram
586+
* the hardware to 5s from now. Any hrtimer_start after that
587+
* will not reprogram the hardware due to hang_detected being
588+
* set. So we'd effectivly block all timers until the T2 event
589+
* fires.
590+
*/
591+
if (cpu_base->hang_detected)
592+
return;
593+
572594
if (cpu_base->expires_next.tv64 != KTIME_MAX)
573595
tick_program_event(cpu_base->expires_next, 1);
574596
}

kernel/timer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
838838

839839
bit = find_last_bit(&mask, BITS_PER_LONG);
840840

841-
mask = (1 << bit) - 1;
841+
mask = (1UL << bit) - 1;
842842

843843
expires_limit = expires_limit & ~(mask);
844844

0 commit comments

Comments
 (0)