android_kernel_sony_sdm845/kernel/time
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Konstantin Khlebnikov 75fc4654a2 clocksource: Prevent double add_timer_on() for watchdog_timer
commit febac332a819f0e764aa4da62757ba21d18c182b upstream.

Kernel crashes inside QEMU/KVM are observed:

  kernel BUG at kernel/time/timer.c:1154!
  BUG_ON(timer_pending(timer) || !timer->function) in add_timer_on().

At the same time another cpu got:

  general protection fault: 0000 [#1] SMP PTI of poinson pointer 0xdead000000000200 in:

  __hlist_del at include/linux/list.h:681
  (inlined by) detach_timer at kernel/time/timer.c:818
  (inlined by) expire_timers at kernel/time/timer.c:1355
  (inlined by) __run_timers at kernel/time/timer.c:1686
  (inlined by) run_timer_softirq at kernel/time/timer.c:1699

Unfortunately kernel logs are badly scrambled, stacktraces are lost.

Printing the timer->function before the BUG_ON() pointed to
clocksource_watchdog().

The execution of clocksource_watchdog() can race with a sequence of
clocksource_stop_watchdog() .. clocksource_start_watchdog():

expire_timers()
 detach_timer(timer, true);
  timer->entry.pprev = NULL;
 raw_spin_unlock_irq(&base->lock);
 call_timer_fn
  clocksource_watchdog()

					clocksource_watchdog_kthread() or
					clocksource_unbind()

					spin_lock_irqsave(&watchdog_lock, flags);
					clocksource_stop_watchdog();
					 del_timer(&watchdog_timer);
					 watchdog_running = 0;
					spin_unlock_irqrestore(&watchdog_lock, flags);

					spin_lock_irqsave(&watchdog_lock, flags);
					clocksource_start_watchdog();
					 add_timer_on(&watchdog_timer, ...);
					 watchdog_running = 1;
					spin_unlock_irqrestore(&watchdog_lock, flags);

  spin_lock(&watchdog_lock);
  add_timer_on(&watchdog_timer, ...);
   BUG_ON(timer_pending(timer) || !timer->function);
    timer_pending() -> true
    BUG()

I.e. inside clocksource_watchdog() watchdog_timer could be already armed.

Check timer_pending() before calling add_timer_on(). This is sufficient as
all operations are synchronized by watchdog_lock.

Fixes: 75c5158f70 ("timekeeping: Update clocksource with stop_machine")
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/158048693917.4378.13823603769948933793.stgit@buzz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-02-14 16:31:08 -05:00
..
alarmtimer.c alarmtimer: Change remaining ENOTSUPP to EOPNOTSUPP 2019-11-10 11:23:32 +01:00
clockevents.c clockevents: Make clockevents_subsys static 2016-07-19 10:48:06 +02:00
clocksource.c clocksource: Prevent double add_timer_on() for watchdog_timer 2020-02-14 16:31:08 -05:00
hrtimer.c hrtimer: Annotate lockless access to timer->state 2020-01-04 13:41:08 +01:00
itimer.c itimers: Handle relative timers with CONFIG_TIME_LOW_RES proper 2016-01-17 11:13:55 +01:00
jiffies.c jiffies: Use CLOCKSOURCE_MASK instead of constant 2016-02-27 08:55:31 +01:00
Kconfig rcu: Drop RCU_USER_QS in favor of NO_HZ_FULL 2015-07-06 13:52:18 -07:00
Makefile time: Remove development rules from Kbuild/Makefile 2015-07-01 09:57:35 +02:00
ntp.c ntp: Limit TAI-UTC offset 2019-08-04 09:33:21 +02:00
ntp_internal.h ntp: Fix second_overflow's input parameter type to be 64bits 2015-12-16 16:50:56 -08:00
posix-clock.c time: Change posix clocks ops interfaces to use timespec64 2018-03-24 11:00:09 +01:00
posix-cpu-timers.c posix-timers: Sanitize overrun handling 2018-11-10 07:43:01 -08:00
posix-timers.c posix-timers: Sanitize overrun handling 2018-11-10 07:43:01 -08:00
sched_clock.c timers, sched_clock: Update timeout for clock wrap 2018-03-22 09:17:42 +01:00
test_udelay.c time: Avoid timespec in udelay_test 2016-06-20 12:47:26 -07:00
tick-broadcast-hrtimer.c tick/broadcast-hrtimer: Set name of the ce_broadcast_hrtimer 2016-07-05 17:02:19 +02:00
tick-broadcast.c tick/broadcast: Use for_each_cpu() specially on UP kernels 2018-05-22 16:57:58 +02:00
tick-common.c clockevents: Remove unused set_mode() callback 2015-09-14 11:00:55 +02:00
tick-internal.h timers: Forward the wheel clock whenever possible 2016-07-07 10:35:11 +02:00
tick-oneshot.c clockevents: Provide functions to set and get the state 2015-06-02 14:40:47 +02:00
tick-sched.c nohz: Fix local_timer_softirq_pending() 2018-08-09 12:17:57 +02:00
tick-sched.h timers/nohz: Convert tick dependency mask to atomic_t 2016-03-29 11:52:11 +02:00
time.c time: Introduce jiffies64_to_nsecs() 2018-10-10 08:53:18 +02:00
timeconst.bc time: Introduce jiffies64_to_nsecs() 2018-10-10 08:53:18 +02:00
timeconv.c time: Add time64_to_tm() 2016-06-20 12:47:15 -07:00
timecounter.c timecounter: keep track of accumulated fractional nanoseconds 2014-12-30 18:29:27 -05:00
timekeeping.c timekeeping: Use proper seqcount initializer 2019-02-12 19:44:54 +01:00
timekeeping.h hrtimer: Make offset update smarter 2015-04-22 17:06:49 +02:00
timekeeping_debug.c timekeeping: Use deferred printk() in debug code 2017-02-23 17:44:36 +01:00
timekeeping_internal.h clocksource: Make clocksource validation work for all clocksources 2015-12-19 15:59:57 +01:00
timer.c timer: Read jiffies once when forwarding base clk 2019-10-17 13:42:06 -07:00
timer_list.c timer_list: Guard procfs specific code 2019-08-04 09:33:21 +02:00
timer_stats.c timer/debug: Change /proc/timer_stats from 0644 to 0600 2019-05-10 17:52:11 +02:00