summaryrefslogtreecommitdiff
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
parentf06bed87d7cdfd51793cbb0111799f39ba75cfa3 (diff)
parentfebac332a819f0e764aa4da62757ba21d18c182b (diff)
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
-rw-r--r--MAINTAINERS2
-rw-r--r--kernel/time/clocksource.c11
2 files changed, 10 insertions, 3 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index c74e4ea714a5..f74871a22c42 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13360,7 +13360,7 @@ S: Maintained
F: fs/timerfd.c
F: include/linux/timer*
F: include/linux/time_namespace.h
-F: kernel/time_namespace.c
+F: kernel/time/namespace.c
F: kernel/time/*timer*
POWER MANAGEMENT CORE
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);
}