diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-09 12:00:12 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-09 12:00:12 -0800 |
commit | 2fbc23c738350f1a47007da7ad92ae2e4ea63951 (patch) | |
tree | 88029f5be09244ef6ebd132486b6f1d2b8b6fa36 | |
parent | f06bed87d7cdfd51793cbb0111799f39ba75cfa3 (diff) | |
parent | febac332a819f0e764aa4da62757ba21d18c182b (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-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 11 |
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); } |