summary refs log tree commit diff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-02-09 12:00:12 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-02-09 12:00:12 -0800
commit2fbc23c738350f1a47007da7ad92ae2e4ea63951 (patch)
tree88029f5be09244ef6ebd132486b6f1d2b8b6fa36 /kernel
parentf06bed87d7cdfd51793cbb0111799f39ba75cfa3 (diff)
parentfebac332a819f0e764aa4da62757ba21d18c182b (diff)
downloadlinux-2fbc23c738350f1a47007da7ad92ae2e4ea63951.tar.gz
Merge tag 'timers-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fixes from Thomas Gleixner:
 "Two small fixes for the time(r) subsystem:

   - Handle a subtle race between the clocksource watchdog and a
     concurrent clocksource watchdog stop/start sequence correctly to
     prevent a timer double add bug.

   - Fix the file path for the core time namespace file"

* tag 'timers-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource: Prevent double add_timer_on() for watchdog_timer
  MAINTAINERS: Correct path to time namespace source file
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/clocksource.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index fff5f64981c6..428beb69426a 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -293,8 +293,15 @@ static void clocksource_watchdog(struct timer_list *unused)
 	next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
 	if (next_cpu >= nr_cpu_ids)
 		next_cpu = cpumask_first(cpu_online_mask);
-	watchdog_timer.expires += WATCHDOG_INTERVAL;
-	add_timer_on(&watchdog_timer, next_cpu);
+
+	/*
+	 * Arm timer if not already pending: could race with concurrent
+	 * pair clocksource_stop_watchdog() clocksource_start_watchdog().
+	 */
+	if (!timer_pending(&watchdog_timer)) {
+		watchdog_timer.expires += WATCHDOG_INTERVAL;
+		add_timer_on(&watchdog_timer, next_cpu);
+	}
 out:
 	spin_unlock(&watchdog_lock);
 }