aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index d8b23a929e66..846d0a1f235e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -29,6 +29,7 @@
29 29
30#define TK_CLEAR_NTP (1 << 0) 30#define TK_CLEAR_NTP (1 << 0)
31#define TK_MIRROR (1 << 1) 31#define TK_MIRROR (1 << 1)
32#define TK_CLOCK_WAS_SET (1 << 2)
32 33
33static struct timekeeper timekeeper; 34static struct timekeeper timekeeper;
34static DEFINE_RAW_SPINLOCK(timekeeper_lock); 35static DEFINE_RAW_SPINLOCK(timekeeper_lock);
@@ -204,9 +205,9 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
204 205
205static RAW_NOTIFIER_HEAD(pvclock_gtod_chain); 206static RAW_NOTIFIER_HEAD(pvclock_gtod_chain);
206 207
207static void update_pvclock_gtod(struct timekeeper *tk) 208static void update_pvclock_gtod(struct timekeeper *tk, bool was_set)
208{ 209{
209 raw_notifier_call_chain(&pvclock_gtod_chain, 0, tk); 210 raw_notifier_call_chain(&pvclock_gtod_chain, was_set, tk);
210} 211}
211 212
212/** 213/**
@@ -220,7 +221,7 @@ int pvclock_gtod_register_notifier(struct notifier_block *nb)
220 221
221 raw_spin_lock_irqsave(&timekeeper_lock, flags); 222 raw_spin_lock_irqsave(&timekeeper_lock, flags);
222 ret = raw_notifier_chain_register(&pvclock_gtod_chain, nb); 223 ret = raw_notifier_chain_register(&pvclock_gtod_chain, nb);
223 update_pvclock_gtod(tk); 224 update_pvclock_gtod(tk, true);
224 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 225 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
225 226
226 return ret; 227 return ret;
@@ -252,7 +253,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
252 ntp_clear(); 253 ntp_clear();
253 } 254 }
254 update_vsyscall(tk); 255 update_vsyscall(tk);
255 update_pvclock_gtod(tk); 256 update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
256 257
257 if (action & TK_MIRROR) 258 if (action & TK_MIRROR)
258 memcpy(&shadow_timekeeper, &timekeeper, sizeof(timekeeper)); 259 memcpy(&shadow_timekeeper, &timekeeper, sizeof(timekeeper));
@@ -512,7 +513,7 @@ int do_settimeofday(const struct timespec *tv)
512 513
513 tk_set_xtime(tk, tv); 514 tk_set_xtime(tk, tv);
514 515
515 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); 516 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
516 517
517 write_seqcount_end(&timekeeper_seq); 518 write_seqcount_end(&timekeeper_seq);
518 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 519 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
@@ -556,7 +557,7 @@ int timekeeping_inject_offset(struct timespec *ts)
556 tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); 557 tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts));
557 558
558error: /* even if we error out, we forwarded the time, so call update */ 559error: /* even if we error out, we forwarded the time, so call update */
559 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); 560 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
560 561
561 write_seqcount_end(&timekeeper_seq); 562 write_seqcount_end(&timekeeper_seq);
562 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 563 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
@@ -646,7 +647,7 @@ static int change_clocksource(void *data)
646 module_put(new->owner); 647 module_put(new->owner);
647 } 648 }
648 } 649 }
649 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); 650 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
650 651
651 write_seqcount_end(&timekeeper_seq); 652 write_seqcount_end(&timekeeper_seq);
652 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 653 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
@@ -887,7 +888,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
887 888
888 __timekeeping_inject_sleeptime(tk, delta); 889 __timekeeping_inject_sleeptime(tk, delta);
889 890
890 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR); 891 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
891 892
892 write_seqcount_end(&timekeeper_seq); 893 write_seqcount_end(&timekeeper_seq);
893 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 894 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
@@ -969,7 +970,7 @@ static void timekeeping_resume(void)
969 tk->cycle_last = clock->cycle_last = cycle_now; 970 tk->cycle_last = clock->cycle_last = cycle_now;
970 tk->ntp_error = 0; 971 tk->ntp_error = 0;
971 timekeeping_suspended = 0; 972 timekeeping_suspended = 0;
972 timekeeping_update(tk, TK_MIRROR); 973 timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET);
973 write_seqcount_end(&timekeeper_seq); 974 write_seqcount_end(&timekeeper_seq);
974 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 975 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
975 976
@@ -1243,9 +1244,10 @@ out_adjust:
1243 * It also calls into the NTP code to handle leapsecond processing. 1244 * It also calls into the NTP code to handle leapsecond processing.
1244 * 1245 *
1245 */ 1246 */
1246static inline void accumulate_nsecs_to_secs(struct timekeeper *tk) 1247static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
1247{ 1248{
1248 u64 nsecps = (u64)NSEC_PER_SEC << tk->shift; 1249 u64 nsecps = (u64)NSEC_PER_SEC << tk->shift;
1250 unsigned int action = 0;
1249 1251
1250 while (tk->xtime_nsec >= nsecps) { 1252 while (tk->xtime_nsec >= nsecps) {
1251 int leap; 1253 int leap;
@@ -1268,8 +1270,10 @@ static inline void accumulate_nsecs_to_secs(struct timekeeper *tk)
1268 __timekeeping_set_tai_offset(tk, tk->tai_offset - leap); 1270 __timekeeping_set_tai_offset(tk, tk->tai_offset - leap);
1269 1271
1270 clock_was_set_delayed(); 1272 clock_was_set_delayed();
1273 action = TK_CLOCK_WAS_SET;
1271 } 1274 }
1272 } 1275 }
1276 return action;
1273} 1277}
1274 1278
1275/** 1279/**
@@ -1354,6 +1358,7 @@ static void update_wall_time(void)
1354 struct timekeeper *tk = &shadow_timekeeper; 1358 struct timekeeper *tk = &shadow_timekeeper;
1355 cycle_t offset; 1359 cycle_t offset;
1356 int shift = 0, maxshift; 1360 int shift = 0, maxshift;
1361 unsigned int action;
1357 unsigned long flags; 1362 unsigned long flags;
1358 1363
1359 raw_spin_lock_irqsave(&timekeeper_lock, flags); 1364 raw_spin_lock_irqsave(&timekeeper_lock, flags);
@@ -1406,7 +1411,7 @@ static void update_wall_time(void)
1406 * Finally, make sure that after the rounding 1411 * Finally, make sure that after the rounding
1407 * xtime_nsec isn't larger than NSEC_PER_SEC 1412 * xtime_nsec isn't larger than NSEC_PER_SEC
1408 */ 1413 */
1409 accumulate_nsecs_to_secs(tk); 1414 action = accumulate_nsecs_to_secs(tk);
1410 1415
1411 write_seqcount_begin(&timekeeper_seq); 1416 write_seqcount_begin(&timekeeper_seq);
1412 /* Update clock->cycle_last with the new value */ 1417 /* Update clock->cycle_last with the new value */
@@ -1422,7 +1427,7 @@ static void update_wall_time(void)
1422 * updating. 1427 * updating.
1423 */ 1428 */
1424 memcpy(real_tk, tk, sizeof(*tk)); 1429 memcpy(real_tk, tk, sizeof(*tk));
1425 timekeeping_update(real_tk, 0); 1430 timekeeping_update(real_tk, action);
1426 write_seqcount_end(&timekeeper_seq); 1431 write_seqcount_end(&timekeeper_seq);
1427out: 1432out:
1428 raw_spin_unlock_irqrestore(&timekeeper_lock, flags); 1433 raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
@@ -1684,6 +1689,7 @@ int do_adjtimex(struct timex *txc)
1684 1689
1685 if (tai != orig_tai) { 1690 if (tai != orig_tai) {
1686 __timekeeping_set_tai_offset(tk, tai); 1691 __timekeeping_set_tai_offset(tk, tai);
1692 update_pvclock_gtod(tk, true);
1687 clock_was_set_delayed(); 1693 clock_was_set_delayed();
1688 } 1694 }
1689 write_seqcount_end(&timekeeper_seq); 1695 write_seqcount_end(&timekeeper_seq);