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

Configure Feed

Select the types of activity you want to include in your feed.

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

+37 -3
+3
Documentation/devicetree/bindings/arm/arch_timer.txt
··· 19 19 20 20 - clock-frequency : The frequency of the main counter, in Hz. Optional. 21 21 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 + 22 25 Example: 23 26 24 27 timer {
+5 -1
drivers/clocksource/arm_arch_timer.c
··· 66 66 static struct clock_event_device __percpu *arch_timer_evt; 67 67 68 68 static bool arch_timer_use_virtual = true; 69 + static bool arch_timer_c3stop; 69 70 static bool arch_timer_mem_use_virtual; 70 71 71 72 /* ··· 264 263 clk->features = CLOCK_EVT_FEAT_ONESHOT; 265 264 266 265 if (type == ARCH_CP15_TIMER) { 267 - clk->features |= CLOCK_EVT_FEAT_C3STOP; 266 + if (arch_timer_c3stop) 267 + clk->features |= CLOCK_EVT_FEAT_C3STOP; 268 268 clk->name = "arch_sys_timer"; 269 269 clk->rating = 450; 270 270 clk->cpumask = cpumask_of(smp_processor_id()); ··· 666 664 return; 667 665 } 668 666 } 667 + 668 + arch_timer_c3stop = !of_property_read_bool(np, "always-on"); 669 669 670 670 arch_timer_register(); 671 671 arch_timer_common_init();
+6 -1
drivers/clocksource/zevio-timer.c
··· 212 212 return ret; 213 213 } 214 214 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);
+22
kernel/hrtimer.c
··· 234 234 goto again; 235 235 } 236 236 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 + } 237 242 } 238 243 return new_base; 239 244 } ··· 573 568 return; 574 569 575 570 cpu_base->expires_next.tv64 = expires_next.tv64; 571 + 572 + /* 573 + * If a hang was detected in the last timer interrupt then we 574 + * leave the hang delay active in the hardware. We want the 575 + * system to make progress. That also prevents the following 576 + * scenario: 577 + * T1 expires 50ms from now 578 + * T2 expires 5s from now 579 + * 580 + * T1 is removed, so this code is called and would reprogram 581 + * the hardware to 5s from now. Any hrtimer_start after that 582 + * will not reprogram the hardware due to hang_detected being 583 + * set. So we'd effectivly block all timers until the T2 event 584 + * fires. 585 + */ 586 + if (cpu_base->hang_detected) 587 + return; 576 588 577 589 if (cpu_base->expires_next.tv64 != KTIME_MAX) 578 590 tick_program_event(cpu_base->expires_next, 1);
+1 -1
kernel/timer.c
··· 838 838 839 839 bit = find_last_bit(&mask, BITS_PER_LONG); 840 840 841 - mask = (1 << bit) - 1; 841 + mask = (1UL << bit) - 1; 842 842 843 843 expires_limit = expires_limit & ~(mask); 844 844