Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d550e81d authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

timers: Reduce __run_timers() latency for empty list



The __run_timers() function currently steps through the list one jiffy at
a time in order to update the timer wheel.  However, if the timer wheel
is empty, no adjustment is needed other than updating ->timer_jiffies.
In this case, which is likely to be common for NO_HZ_FULL kernels, the
kernel currently incurs a large latency for no good reason.  This commit
therefore short-circuits this case.

Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: default avatarJosh Triplett <josh@joshtriplett.org>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Reviewed-by: default avatarOleg Nesterov <oleg@redhat.com>
Reviewed-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Tested-by: default avatarMike Galbraith <bitbucket@online.de>
parent fff42158
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -338,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz)
}
EXPORT_SYMBOL_GPL(set_timer_slack);

/*
 * If the list is empty, catch up ->timer_jiffies to the current time.
 * The caller must hold the tvec_base lock.  Returns true if the list
 * was empty and therefore ->timer_jiffies was updated.
 */
static bool catchup_timer_jiffies(struct tvec_base *base)
{
	if (!base->all_timers) {
		base->timer_jiffies = jiffies;
		return true;
	}
	return false;
}

static void
__internal_add_timer(struct tvec_base *base, struct timer_list *timer)
{
@@ -1150,6 +1164,10 @@ static inline void __run_timers(struct tvec_base *base)
	struct timer_list *timer;

	spin_lock_irq(&base->lock);
	if (catchup_timer_jiffies(base)) {
		spin_unlock_irq(&base->lock);
		return;
	}
	while (time_after_eq(jiffies, base->timer_jiffies)) {
		struct list_head work_list;
		struct list_head *head = &work_list;