diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-09 21:00:12 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-02-09 21:00:12 +0100 |
commit | 2fbc23c738350f1a47007da7ad92ae2e4ea63951 (patch) | |
tree | 88029f5be09244ef6ebd132486b6f1d2b8b6fa36 /kernel | |
parent | Merge tag 'irq-urgent-2020-02-09' of git://git.kernel.org/pub/scm/linux/kerne... (diff) | |
parent | clocksource: Prevent double add_timer_on() for watchdog_timer (diff) | |
download | linux-2fbc23c738350f1a47007da7ad92ae2e4ea63951.tar.xz linux-2fbc23c738350f1a47007da7ad92ae2e4ea63951.zip |
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.c | 11 |
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); } |