mirror of https://gitee.com/openkylin/linux.git
time: Fix change_clocksource locking
change_clocksource() fails to grab locks or call timekeeping_update(), which leaves a race window for time inconsistencies. This adds proper locking and a call to timekeeping_update() to fix this. CC: Andy Lutomirski <luto@amacapital.net> CC: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
a939e817aa
commit
f695cf9483
|
@ -448,9 +448,12 @@ EXPORT_SYMBOL(timekeeping_inject_offset);
|
|||
static int change_clocksource(void *data)
|
||||
{
|
||||
struct clocksource *new, *old;
|
||||
unsigned long flags;
|
||||
|
||||
new = (struct clocksource *) data;
|
||||
|
||||
write_seqlock_irqsave(&timekeeper.lock, flags);
|
||||
|
||||
timekeeping_forward_now();
|
||||
if (!new->enable || new->enable(new) == 0) {
|
||||
old = timekeeper.clock;
|
||||
|
@ -458,6 +461,10 @@ static int change_clocksource(void *data)
|
|||
if (old->disable)
|
||||
old->disable(old);
|
||||
}
|
||||
timekeeping_update(true);
|
||||
|
||||
write_sequnlock_irqrestore(&timekeeper.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue