diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/time/timer.c | 22 | 
1 files changed, 6 insertions, 16 deletions
| diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 4f78a7bff9e1..8b3fb52d8c47 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -205,7 +205,6 @@ struct timer_base {  	unsigned long		next_expiry;  	unsigned int		cpu;  	bool			is_idle; -	bool			must_forward_clk;  	DECLARE_BITMAP(pending_map, WHEEL_SIZE);  	struct hlist_head	vectors[WHEEL_SIZE];  } ____cacheline_aligned; @@ -888,12 +887,13 @@ get_target_base(struct timer_base *base, unsigned tflags)  static inline void forward_timer_base(struct timer_base *base)  { -	unsigned long jnow; +	unsigned long jnow = READ_ONCE(jiffies); -	if (!base->must_forward_clk) -		return; - -	jnow = READ_ONCE(jiffies); +	/* +	 * No need to forward if we are close enough below jiffies. +	 * Also while executing timers, base->clk is 1 offset ahead +	 * of jiffies to avoid endless requeuing to current jffies. +	 */  	if ((long)(jnow - base->clk) < 2)  		return; @@ -1722,16 +1722,8 @@ static inline void __run_timers(struct timer_base *base)  	timer_base_lock_expiry(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. -	 */ -	base->must_forward_clk = false; -  	while (time_after_eq(jiffies, base->clk) &&  	       time_after_eq(jiffies, base->next_expiry)) { -  		levels = collect_expired_timers(base, heads);  		base->clk++;  		base->next_expiry = __next_timer_interrupt(base); @@ -1739,7 +1731,6 @@ static inline void __run_timers(struct timer_base *base)  		while (levels--)  			expire_timers(base, heads + levels);  	} -	base->must_forward_clk = true;  	raw_spin_unlock_irq(&base->lock);  	timer_base_unlock_expiry(base);  } @@ -1935,7 +1926,6 @@ int timers_prepare_cpu(unsigned int cpu)  		base->clk = jiffies;  		base->next_expiry = base->clk + NEXT_TIMER_MAX_DELTA;  		base->is_idle = false; -		base->must_forward_clk = true;  	}  	return 0;  } | 
