diff options
Diffstat (limited to 'kernel/time/timer.c')
| -rw-r--r-- | kernel/time/timer.c | 31 | 
1 files changed, 17 insertions, 14 deletions
| diff --git a/kernel/time/timer.c b/kernel/time/timer.c index cc2d23e6ff61..fa49cd753dea 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -581,7 +581,7 @@ trigger_dyntick_cpu(struct timer_base *base, struct timer_list *timer)  	 * wheel:  	 */  	base->next_expiry = timer->expires; -		wake_up_nohz_cpu(base->cpu); +	wake_up_nohz_cpu(base->cpu);  }  static void @@ -1657,6 +1657,22 @@ static inline void __run_timers(struct timer_base *base)  	raw_spin_lock_irq(&base->lock); +	/* +	 * timer_base::must_forward_clk must be cleared before running +	 * timers so that any timer functions that call mod_timer() will +	 * not try to forward the base. Idle tracking / clock forwarding +	 * logic is only used with BASE_STD timers. +	 * +	 * The must_forward_clk flag is cleared unconditionally also for +	 * the deferrable base. The deferrable base is not affected by idle +	 * tracking and never forwarded, so clearing the flag is a NOOP. +	 * +	 * The fact that the deferrable base is never forwarded can cause +	 * large variations in granularity for deferrable timers, but they +	 * can be deferred for long periods due to idle anyway. +	 */ +	base->must_forward_clk = false; +  	while (time_after_eq(jiffies, base->clk)) {  		levels = collect_expired_timers(base, heads); @@ -1676,19 +1692,6 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h)  {  	struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); -	/* -	 * must_forward_clk must be cleared before running timers so that any -	 * timer functions that call mod_timer will not try to forward the -	 * base. idle trcking / clock forwarding logic is only used with -	 * BASE_STD timers. -	 * -	 * The deferrable base does not do idle tracking at all, so we do -	 * not forward it. This can result in very large variations in -	 * granularity for deferrable timers, but they can be deferred for -	 * long periods due to idle. -	 */ -	base->must_forward_clk = false; -  	__run_timers(base);  	if (IS_ENABLED(CONFIG_NO_HZ_COMMON))  		__run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); | 
