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:
"A pile of fixes for long standing issues with the timer wheel and the
NOHZ code:

- Prevent timer base confusion accross the nohz switch, which can
cause unlocked access and data corruption

- Reinitialize the stale base clock on cpu hotplug to prevent subtle
side effects including rollovers on 32bit

- Prevent an interrupt storm when the timer softirq is already
pending caused by tick_nohz_stop_sched_tick()

- Move the timer start tracepoint to a place where it actually makes
sense

- Add documentation to timerqueue functions as they caused confusion
several times now"

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
timerqueue: Document return values of timerqueue_add/del()
timers: Invoke timer_start_debug() where it makes sense
nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick()
timers: Reinitialize per cpu bases on hotplug
timers: Use deferrable base independent of base::nohz_active

+52 -20
+1 -1
include/linux/cpuhotplug.h
··· 86 86 CPUHP_MM_ZSWP_POOL_PREPARE, 87 87 CPUHP_KVM_PPC_BOOK3S_PREPARE, 88 88 CPUHP_ZCOMP_PREPARE, 89 - CPUHP_TIMERS_DEAD, 89 + CPUHP_TIMERS_PREPARE, 90 90 CPUHP_MIPS_SOC_PREPARE, 91 91 CPUHP_BP_PREPARE_DYN, 92 92 CPUHP_BP_PREPARE_DYN_END = CPUHP_BP_PREPARE_DYN + 20,
+3 -1
include/linux/timer.h
··· 207 207 unsigned long round_jiffies_up_relative(unsigned long j); 208 208 209 209 #ifdef CONFIG_HOTPLUG_CPU 210 + int timers_prepare_cpu(unsigned int cpu); 210 211 int timers_dead_cpu(unsigned int cpu); 211 212 #else 212 - #define timers_dead_cpu NULL 213 + #define timers_prepare_cpu NULL 214 + #define timers_dead_cpu NULL 213 215 #endif 214 216 215 217 #endif
+2 -2
kernel/cpu.c
··· 1277 1277 * before blk_mq_queue_reinit_notify() from notify_dead(), 1278 1278 * otherwise a RCU stall occurs. 1279 1279 */ 1280 - [CPUHP_TIMERS_DEAD] = { 1280 + [CPUHP_TIMERS_PREPARE] = { 1281 1281 .name = "timers:dead", 1282 - .startup.single = NULL, 1282 + .startup.single = timers_prepare_cpu, 1283 1283 .teardown.single = timers_dead_cpu, 1284 1284 }, 1285 1285 /* Kicks the plugged cpu into life */
+17 -2
kernel/time/tick-sched.c
··· 650 650 ts->next_tick = 0; 651 651 } 652 652 653 + static inline bool local_timer_softirq_pending(void) 654 + { 655 + return local_softirq_pending() & TIMER_SOFTIRQ; 656 + } 657 + 653 658 static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, 654 659 ktime_t now, int cpu) 655 660 { ··· 671 666 } while (read_seqretry(&jiffies_lock, seq)); 672 667 ts->last_jiffies = basejiff; 673 668 674 - if (rcu_needs_cpu(basemono, &next_rcu) || 675 - arch_needs_cpu() || irq_work_needs_cpu()) { 669 + /* 670 + * Keep the periodic tick, when RCU, architecture or irq_work 671 + * requests it. 672 + * Aside of that check whether the local timer softirq is 673 + * pending. If so its a bad idea to call get_next_timer_interrupt() 674 + * because there is an already expired timer, so it will request 675 + * immeditate expiry, which rearms the hardware timer with a 676 + * minimal delta which brings us back to this place 677 + * immediately. Lather, rinse and repeat... 678 + */ 679 + if (rcu_needs_cpu(basemono, &next_rcu) || arch_needs_cpu() || 680 + irq_work_needs_cpu() || local_timer_softirq_pending()) { 676 681 next_tick = basemono + TICK_NSEC; 677 682 } else { 678 683 /*
+24 -11
kernel/time/timer.c
··· 823 823 struct timer_base *base = per_cpu_ptr(&timer_bases[BASE_STD], cpu); 824 824 825 825 /* 826 - * If the timer is deferrable and nohz is active then we need to use 827 - * the deferrable base. 826 + * If the timer is deferrable and NO_HZ_COMMON is set then we need 827 + * to use the deferrable base. 828 828 */ 829 - if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active && 830 - (tflags & TIMER_DEFERRABLE)) 829 + if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE)) 831 830 base = per_cpu_ptr(&timer_bases[BASE_DEF], cpu); 832 831 return base; 833 832 } ··· 836 837 struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); 837 838 838 839 /* 839 - * If the timer is deferrable and nohz is active then we need to use 840 - * the deferrable base. 840 + * If the timer is deferrable and NO_HZ_COMMON is set then we need 841 + * to use the deferrable base. 841 842 */ 842 - if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active && 843 - (tflags & TIMER_DEFERRABLE)) 843 + if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE)) 844 844 base = this_cpu_ptr(&timer_bases[BASE_DEF]); 845 845 return base; 846 846 } ··· 1007 1009 if (!ret && (options & MOD_TIMER_PENDING_ONLY)) 1008 1010 goto out_unlock; 1009 1011 1010 - debug_activate(timer, expires); 1011 - 1012 1012 new_base = get_target_base(base, timer->flags); 1013 1013 1014 1014 if (base != new_base) { ··· 1029 1033 forward_timer_base(base); 1030 1034 } 1031 1035 } 1036 + 1037 + debug_activate(timer, expires); 1032 1038 1033 1039 timer->expires = expires; 1034 1040 /* ··· 1682 1684 base->must_forward_clk = false; 1683 1685 1684 1686 __run_timers(base); 1685 - if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) 1687 + if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) 1686 1688 __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); 1687 1689 } 1688 1690 ··· 1851 1853 timer->flags = (timer->flags & ~TIMER_BASEMASK) | cpu; 1852 1854 internal_add_timer(new_base, timer); 1853 1855 } 1856 + } 1857 + 1858 + int timers_prepare_cpu(unsigned int cpu) 1859 + { 1860 + struct timer_base *base; 1861 + int b; 1862 + 1863 + for (b = 0; b < NR_BASES; b++) { 1864 + base = per_cpu_ptr(&timer_bases[b], cpu); 1865 + base->clk = jiffies; 1866 + base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA; 1867 + base->is_idle = false; 1868 + base->must_forward_clk = true; 1869 + } 1870 + return 0; 1854 1871 } 1855 1872 1856 1873 int timers_dead_cpu(unsigned int cpu)
+5 -3
lib/timerqueue.c
··· 33 33 * @head: head of timerqueue 34 34 * @node: timer node to be added 35 35 * 36 - * Adds the timer node to the timerqueue, sorted by the 37 - * node's expires value. 36 + * Adds the timer node to the timerqueue, sorted by the node's expires 37 + * value. Returns true if the newly added timer is the first expiring timer in 38 + * the queue. 38 39 */ 39 40 bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) 40 41 { ··· 71 70 * @head: head of timerqueue 72 71 * @node: timer node to be removed 73 72 * 74 - * Removes the timer node from the timerqueue. 73 + * Removes the timer node from the timerqueue. Returns true if the queue is 74 + * not empty after the remove. 75 75 */ 76 76 bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node) 77 77 {