Skip to contentSkip to conversation

Patch "timers: Use deferrable base independent of base::nohz_active" has been added to the 4.14-stable tree

PATCH [email protected] 1 participant 1 message Jan 1, 2018

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

timers: Use deferrable base independent of base::nohz_active

to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
timers-use-deferrable-base-independent-of-base-nohz_active.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From ced6d5c11d3e7b342f1a80f908e6756ebd4b8ddd Mon Sep 17 00:00:00 2001

From: Anna-Maria Gleixner <[email protected]>
Date: Fri, 22 Dec 2017 15:51:12 +0100
Subject: timers: Use deferrable base independent of base::nohz_active

From: Anna-Maria Gleixner <[email protected]>

commit ced6d5c11d3e7b342f1a80f908e6756ebd4b8ddd upstream.

During boot and before base::nohz_active is set in the timer bases, deferrable timers are enqueued into the standard timer base. This works correctly as long as base::nohz_active is false.

Once it base::nohz_active is set and a timer which was enqueued before that is accessed the lock selector code choses the lock of the deferred base. This causes unlocked access to the standard base and in case the timer is removed it does not clear the pending flag in the standard base bitmap which causes get_next_timer_interrupt() to return bogus values.

To prevent that, the deferrable timers must be enqueued in the deferrable base, even when base::nohz_active is not set. Those deferrable timers also need to be expired unconditional.

Fixes 500462a9de65 ("timers: Switch to a non-cascading wheel")
Cc Peter Zijlstra <[email protected]>
Cc Sebastian Siewior <[email protected]>
Cc Paul McKenney <[email protected]>
---
 kernel/time/timer.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
kernel/time/timer.c +7 -9
@@ -814,11 +814,10 @@ static inline struct timer_base *get_tim
 	struct timer_base *base = per_cpu_ptr(&timer_bases[BASE_STD], cpu);
 
 	/*
-	 * If the timer is deferrable and nohz is active then we need to use
-	 * the deferrable base.
+	 * If the timer is deferrable and NO_HZ_COMMON is set then we need
+	 * to use the deferrable base.
 	 */
-	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
-	    (tflags & TIMER_DEFERRABLE))
+	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE))
 		base = per_cpu_ptr(&timer_bases[BASE_DEF], cpu);
 	return base;
 }
@@ -828,11 +827,10 @@ static inline struct timer_base *get_tim
 	struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
 
 	/*
-	 * If the timer is deferrable and nohz is active then we need to use
-	 * the deferrable base.
+	 * If the timer is deferrable and NO_HZ_COMMON is set then we need
+	 * to use the deferrable base.
 	 */
-	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
-	    (tflags & TIMER_DEFERRABLE))
+	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE))
 		base = this_cpu_ptr(&timer_bases[BASE_DEF]);
 	return base;
 }
@@ -1644,7 +1642,7 @@ static __latent_entropy void run_timer_s
 	base->must_forward_clk = false;
 
 	__run_timers(base);
-	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active)
+	if (IS_ENABLED(CONFIG_NO_HZ_COMMON))
 		__run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]));
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.14/nohz-prevent-a-timer-interrupt-storm-in-tick_nohz_stop_sched_tick.patch queue-4.14/timers-invoke-timer_start_debug-where-it-makes-sense.patch queue-4.14/timers-use-deferrable-base-independent-of-base-nohz_active.patch queue-4.14/timers-reinitialize-per-cpu-bases-on-hotplug.patch