diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/timekeeping.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 838fc0777b68..d8b23a929e66 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "ntp_internal.h" | 27 | #include "ntp_internal.h" |
28 | #include "timekeeping_internal.h" | 28 | #include "timekeeping_internal.h" |
29 | 29 | ||
30 | #define TK_CLEAR_NTP (1 << 0) | ||
31 | #define TK_MIRROR (1 << 1) | ||
32 | |||
30 | static struct timekeeper timekeeper; | 33 | static struct timekeeper timekeeper; |
31 | static DEFINE_RAW_SPINLOCK(timekeeper_lock); | 34 | static DEFINE_RAW_SPINLOCK(timekeeper_lock); |
32 | static seqcount_t timekeeper_seq; | 35 | static seqcount_t timekeeper_seq; |
@@ -242,16 +245,16 @@ int pvclock_gtod_unregister_notifier(struct notifier_block *nb) | |||
242 | EXPORT_SYMBOL_GPL(pvclock_gtod_unregister_notifier); | 245 | EXPORT_SYMBOL_GPL(pvclock_gtod_unregister_notifier); |
243 | 246 | ||
244 | /* must hold timekeeper_lock */ | 247 | /* must hold timekeeper_lock */ |
245 | static void timekeeping_update(struct timekeeper *tk, bool clearntp, bool mirror) | 248 | static void timekeeping_update(struct timekeeper *tk, unsigned int action) |
246 | { | 249 | { |
247 | if (clearntp) { | 250 | if (action & TK_CLEAR_NTP) { |
248 | tk->ntp_error = 0; | 251 | tk->ntp_error = 0; |
249 | ntp_clear(); | 252 | ntp_clear(); |
250 | } | 253 | } |
251 | update_vsyscall(tk); | 254 | update_vsyscall(tk); |
252 | update_pvclock_gtod(tk); | 255 | update_pvclock_gtod(tk); |
253 | 256 | ||
254 | if (mirror) | 257 | if (action & TK_MIRROR) |
255 | memcpy(&shadow_timekeeper, &timekeeper, sizeof(timekeeper)); | 258 | memcpy(&shadow_timekeeper, &timekeeper, sizeof(timekeeper)); |
256 | } | 259 | } |
257 | 260 | ||
@@ -509,7 +512,7 @@ int do_settimeofday(const struct timespec *tv) | |||
509 | 512 | ||
510 | tk_set_xtime(tk, tv); | 513 | tk_set_xtime(tk, tv); |
511 | 514 | ||
512 | timekeeping_update(tk, true, true); | 515 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); |
513 | 516 | ||
514 | write_seqcount_end(&timekeeper_seq); | 517 | write_seqcount_end(&timekeeper_seq); |
515 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 518 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
@@ -553,7 +556,7 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
553 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); | 556 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); |
554 | 557 | ||
555 | error: /* even if we error out, we forwarded the time, so call update */ | 558 | error: /* even if we error out, we forwarded the time, so call update */ |
556 | timekeeping_update(tk, true, true); | 559 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); |
557 | 560 | ||
558 | write_seqcount_end(&timekeeper_seq); | 561 | write_seqcount_end(&timekeeper_seq); |
559 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 562 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
@@ -643,7 +646,7 @@ static int change_clocksource(void *data) | |||
643 | module_put(new->owner); | 646 | module_put(new->owner); |
644 | } | 647 | } |
645 | } | 648 | } |
646 | timekeeping_update(tk, true, true); | 649 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); |
647 | 650 | ||
648 | write_seqcount_end(&timekeeper_seq); | 651 | write_seqcount_end(&timekeeper_seq); |
649 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 652 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
@@ -884,7 +887,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta) | |||
884 | 887 | ||
885 | __timekeeping_inject_sleeptime(tk, delta); | 888 | __timekeeping_inject_sleeptime(tk, delta); |
886 | 889 | ||
887 | timekeeping_update(tk, true, true); | 890 | timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); |
888 | 891 | ||
889 | write_seqcount_end(&timekeeper_seq); | 892 | write_seqcount_end(&timekeeper_seq); |
890 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 893 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
@@ -966,7 +969,7 @@ static void timekeeping_resume(void) | |||
966 | tk->cycle_last = clock->cycle_last = cycle_now; | 969 | tk->cycle_last = clock->cycle_last = cycle_now; |
967 | tk->ntp_error = 0; | 970 | tk->ntp_error = 0; |
968 | timekeeping_suspended = 0; | 971 | timekeeping_suspended = 0; |
969 | timekeeping_update(tk, false, true); | 972 | timekeeping_update(tk, TK_MIRROR); |
970 | write_seqcount_end(&timekeeper_seq); | 973 | write_seqcount_end(&timekeeper_seq); |
971 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 974 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
972 | 975 | ||
@@ -1419,7 +1422,7 @@ static void update_wall_time(void) | |||
1419 | * updating. | 1422 | * updating. |
1420 | */ | 1423 | */ |
1421 | memcpy(real_tk, tk, sizeof(*tk)); | 1424 | memcpy(real_tk, tk, sizeof(*tk)); |
1422 | timekeeping_update(real_tk, false, false); | 1425 | timekeeping_update(real_tk, 0); |
1423 | write_seqcount_end(&timekeeper_seq); | 1426 | write_seqcount_end(&timekeeper_seq); |
1424 | out: | 1427 | out: |
1425 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 1428 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |