diff options
Diffstat (limited to 'kernel/time/ntp.c')
-rw-r--r-- | kernel/time/ntp.c | 191 |
1 files changed, 92 insertions, 99 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index f6117a4c7cb8..f03fd83b170b 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -22,17 +22,18 @@ | |||
22 | * NTP timekeeping variables: | 22 | * NTP timekeeping variables: |
23 | */ | 23 | */ |
24 | 24 | ||
25 | DEFINE_SPINLOCK(ntp_lock); | ||
26 | |||
27 | |||
25 | /* USER_HZ period (usecs): */ | 28 | /* USER_HZ period (usecs): */ |
26 | unsigned long tick_usec = TICK_USEC; | 29 | unsigned long tick_usec = TICK_USEC; |
27 | 30 | ||
28 | /* ACTHZ period (nsecs): */ | 31 | /* ACTHZ period (nsecs): */ |
29 | unsigned long tick_nsec; | 32 | unsigned long tick_nsec; |
30 | 33 | ||
31 | u64 tick_length; | 34 | static u64 tick_length; |
32 | static u64 tick_length_base; | 35 | static u64 tick_length_base; |
33 | 36 | ||
34 | static struct hrtimer leap_timer; | ||
35 | |||
36 | #define MAX_TICKADJ 500LL /* usecs */ | 37 | #define MAX_TICKADJ 500LL /* usecs */ |
37 | #define MAX_TICKADJ_SCALED \ | 38 | #define MAX_TICKADJ_SCALED \ |
38 | (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) | 39 | (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) |
@@ -49,7 +50,7 @@ static struct hrtimer leap_timer; | |||
49 | static int time_state = TIME_OK; | 50 | static int time_state = TIME_OK; |
50 | 51 | ||
51 | /* clock status bits: */ | 52 | /* clock status bits: */ |
52 | int time_status = STA_UNSYNC; | 53 | static int time_status = STA_UNSYNC; |
53 | 54 | ||
54 | /* TAI offset (secs): */ | 55 | /* TAI offset (secs): */ |
55 | static long time_tai; | 56 | static long time_tai; |
@@ -133,7 +134,7 @@ static inline void pps_reset_freq_interval(void) | |||
133 | /** | 134 | /** |
134 | * pps_clear - Clears the PPS state variables | 135 | * pps_clear - Clears the PPS state variables |
135 | * | 136 | * |
136 | * Must be called while holding a write on the xtime_lock | 137 | * Must be called while holding a write on the ntp_lock |
137 | */ | 138 | */ |
138 | static inline void pps_clear(void) | 139 | static inline void pps_clear(void) |
139 | { | 140 | { |
@@ -149,7 +150,7 @@ static inline void pps_clear(void) | |||
149 | * the last PPS signal. When it reaches 0, indicate that PPS signal is | 150 | * the last PPS signal. When it reaches 0, indicate that PPS signal is |
150 | * missing. | 151 | * missing. |
151 | * | 152 | * |
152 | * Must be called while holding a write on the xtime_lock | 153 | * Must be called while holding a write on the ntp_lock |
153 | */ | 154 | */ |
154 | static inline void pps_dec_valid(void) | 155 | static inline void pps_dec_valid(void) |
155 | { | 156 | { |
@@ -233,6 +234,17 @@ static inline void pps_fill_timex(struct timex *txc) | |||
233 | 234 | ||
234 | #endif /* CONFIG_NTP_PPS */ | 235 | #endif /* CONFIG_NTP_PPS */ |
235 | 236 | ||
237 | |||
238 | /** | ||
239 | * ntp_synced - Returns 1 if the NTP status is not UNSYNC | ||
240 | * | ||
241 | */ | ||
242 | static inline int ntp_synced(void) | ||
243 | { | ||
244 | return !(time_status & STA_UNSYNC); | ||
245 | } | ||
246 | |||
247 | |||
236 | /* | 248 | /* |
237 | * NTP methods: | 249 | * NTP methods: |
238 | */ | 250 | */ |
@@ -275,7 +287,7 @@ static inline s64 ntp_update_offset_fll(s64 offset64, long secs) | |||
275 | 287 | ||
276 | time_status |= STA_MODE; | 288 | time_status |= STA_MODE; |
277 | 289 | ||
278 | return div_s64(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs); | 290 | return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs); |
279 | } | 291 | } |
280 | 292 | ||
281 | static void ntp_update_offset(long offset) | 293 | static void ntp_update_offset(long offset) |
@@ -330,11 +342,13 @@ static void ntp_update_offset(long offset) | |||
330 | 342 | ||
331 | /** | 343 | /** |
332 | * ntp_clear - Clears the NTP state variables | 344 | * ntp_clear - Clears the NTP state variables |
333 | * | ||
334 | * Must be called while holding a write on the xtime_lock | ||
335 | */ | 345 | */ |
336 | void ntp_clear(void) | 346 | void ntp_clear(void) |
337 | { | 347 | { |
348 | unsigned long flags; | ||
349 | |||
350 | spin_lock_irqsave(&ntp_lock, flags); | ||
351 | |||
338 | time_adjust = 0; /* stop active adjtime() */ | 352 | time_adjust = 0; /* stop active adjtime() */ |
339 | time_status |= STA_UNSYNC; | 353 | time_status |= STA_UNSYNC; |
340 | time_maxerror = NTP_PHASE_LIMIT; | 354 | time_maxerror = NTP_PHASE_LIMIT; |
@@ -347,63 +361,81 @@ void ntp_clear(void) | |||
347 | 361 | ||
348 | /* Clear PPS state variables */ | 362 | /* Clear PPS state variables */ |
349 | pps_clear(); | 363 | pps_clear(); |
364 | spin_unlock_irqrestore(&ntp_lock, flags); | ||
365 | |||
366 | } | ||
367 | |||
368 | |||
369 | u64 ntp_tick_length(void) | ||
370 | { | ||
371 | unsigned long flags; | ||
372 | s64 ret; | ||
373 | |||
374 | spin_lock_irqsave(&ntp_lock, flags); | ||
375 | ret = tick_length; | ||
376 | spin_unlock_irqrestore(&ntp_lock, flags); | ||
377 | return ret; | ||
350 | } | 378 | } |
351 | 379 | ||
380 | |||
352 | /* | 381 | /* |
353 | * Leap second processing. If in leap-insert state at the end of the | 382 | * this routine handles the overflow of the microsecond field |
354 | * day, the system clock is set back one second; if in leap-delete | 383 | * |
355 | * state, the system clock is set ahead one second. | 384 | * The tricky bits of code to handle the accurate clock support |
385 | * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. | ||
386 | * They were originally developed for SUN and DEC kernels. | ||
387 | * All the kudos should go to Dave for this stuff. | ||
388 | * | ||
389 | * Also handles leap second processing, and returns leap offset | ||
356 | */ | 390 | */ |
357 | static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) | 391 | int second_overflow(unsigned long secs) |
358 | { | 392 | { |
359 | enum hrtimer_restart res = HRTIMER_NORESTART; | 393 | s64 delta; |
394 | int leap = 0; | ||
395 | unsigned long flags; | ||
360 | 396 | ||
361 | write_seqlock(&xtime_lock); | 397 | spin_lock_irqsave(&ntp_lock, flags); |
362 | 398 | ||
399 | /* | ||
400 | * Leap second processing. If in leap-insert state at the end of the | ||
401 | * day, the system clock is set back one second; if in leap-delete | ||
402 | * state, the system clock is set ahead one second. | ||
403 | */ | ||
363 | switch (time_state) { | 404 | switch (time_state) { |
364 | case TIME_OK: | 405 | case TIME_OK: |
406 | if (time_status & STA_INS) | ||
407 | time_state = TIME_INS; | ||
408 | else if (time_status & STA_DEL) | ||
409 | time_state = TIME_DEL; | ||
365 | break; | 410 | break; |
366 | case TIME_INS: | 411 | case TIME_INS: |
367 | timekeeping_leap_insert(-1); | 412 | if (secs % 86400 == 0) { |
368 | time_state = TIME_OOP; | 413 | leap = -1; |
369 | printk(KERN_NOTICE | 414 | time_state = TIME_OOP; |
370 | "Clock: inserting leap second 23:59:60 UTC\n"); | 415 | printk(KERN_NOTICE |
371 | hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC); | 416 | "Clock: inserting leap second 23:59:60 UTC\n"); |
372 | res = HRTIMER_RESTART; | 417 | } |
373 | break; | 418 | break; |
374 | case TIME_DEL: | 419 | case TIME_DEL: |
375 | timekeeping_leap_insert(1); | 420 | if ((secs + 1) % 86400 == 0) { |
376 | time_tai--; | 421 | leap = 1; |
377 | time_state = TIME_WAIT; | 422 | time_tai--; |
378 | printk(KERN_NOTICE | 423 | time_state = TIME_WAIT; |
379 | "Clock: deleting leap second 23:59:59 UTC\n"); | 424 | printk(KERN_NOTICE |
425 | "Clock: deleting leap second 23:59:59 UTC\n"); | ||
426 | } | ||
380 | break; | 427 | break; |
381 | case TIME_OOP: | 428 | case TIME_OOP: |
382 | time_tai++; | 429 | time_tai++; |
383 | time_state = TIME_WAIT; | 430 | time_state = TIME_WAIT; |
384 | /* fall through */ | 431 | break; |
432 | |||
385 | case TIME_WAIT: | 433 | case TIME_WAIT: |
386 | if (!(time_status & (STA_INS | STA_DEL))) | 434 | if (!(time_status & (STA_INS | STA_DEL))) |
387 | time_state = TIME_OK; | 435 | time_state = TIME_OK; |
388 | break; | 436 | break; |
389 | } | 437 | } |
390 | 438 | ||
391 | write_sequnlock(&xtime_lock); | ||
392 | |||
393 | return res; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * this routine handles the overflow of the microsecond field | ||
398 | * | ||
399 | * The tricky bits of code to handle the accurate clock support | ||
400 | * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. | ||
401 | * They were originally developed for SUN and DEC kernels. | ||
402 | * All the kudos should go to Dave for this stuff. | ||
403 | */ | ||
404 | void second_overflow(void) | ||
405 | { | ||
406 | s64 delta; | ||
407 | 439 | ||
408 | /* Bump the maxerror field */ | 440 | /* Bump the maxerror field */ |
409 | time_maxerror += MAXFREQ / NSEC_PER_USEC; | 441 | time_maxerror += MAXFREQ / NSEC_PER_USEC; |
@@ -423,30 +455,34 @@ void second_overflow(void) | |||
423 | pps_dec_valid(); | 455 | pps_dec_valid(); |
424 | 456 | ||
425 | if (!time_adjust) | 457 | if (!time_adjust) |
426 | return; | 458 | goto out; |
427 | 459 | ||
428 | if (time_adjust > MAX_TICKADJ) { | 460 | if (time_adjust > MAX_TICKADJ) { |
429 | time_adjust -= MAX_TICKADJ; | 461 | time_adjust -= MAX_TICKADJ; |
430 | tick_length += MAX_TICKADJ_SCALED; | 462 | tick_length += MAX_TICKADJ_SCALED; |
431 | return; | 463 | goto out; |
432 | } | 464 | } |
433 | 465 | ||
434 | if (time_adjust < -MAX_TICKADJ) { | 466 | if (time_adjust < -MAX_TICKADJ) { |
435 | time_adjust += MAX_TICKADJ; | 467 | time_adjust += MAX_TICKADJ; |
436 | tick_length -= MAX_TICKADJ_SCALED; | 468 | tick_length -= MAX_TICKADJ_SCALED; |
437 | return; | 469 | goto out; |
438 | } | 470 | } |
439 | 471 | ||
440 | tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) | 472 | tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) |
441 | << NTP_SCALE_SHIFT; | 473 | << NTP_SCALE_SHIFT; |
442 | time_adjust = 0; | 474 | time_adjust = 0; |
475 | |||
476 | |||
477 | |||
478 | out: | ||
479 | spin_unlock_irqrestore(&ntp_lock, flags); | ||
480 | |||
481 | return leap; | ||
443 | } | 482 | } |
444 | 483 | ||
445 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | 484 | #ifdef CONFIG_GENERIC_CMOS_UPDATE |
446 | 485 | ||
447 | /* Disable the cmos update - used by virtualization and embedded */ | ||
448 | int no_sync_cmos_clock __read_mostly; | ||
449 | |||
450 | static void sync_cmos_clock(struct work_struct *work); | 486 | static void sync_cmos_clock(struct work_struct *work); |
451 | 487 | ||
452 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); | 488 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); |
@@ -493,35 +529,13 @@ static void sync_cmos_clock(struct work_struct *work) | |||
493 | 529 | ||
494 | static void notify_cmos_timer(void) | 530 | static void notify_cmos_timer(void) |
495 | { | 531 | { |
496 | if (!no_sync_cmos_clock) | 532 | schedule_delayed_work(&sync_cmos_work, 0); |
497 | schedule_delayed_work(&sync_cmos_work, 0); | ||
498 | } | 533 | } |
499 | 534 | ||
500 | #else | 535 | #else |
501 | static inline void notify_cmos_timer(void) { } | 536 | static inline void notify_cmos_timer(void) { } |
502 | #endif | 537 | #endif |
503 | 538 | ||
504 | /* | ||
505 | * Start the leap seconds timer: | ||
506 | */ | ||
507 | static inline void ntp_start_leap_timer(struct timespec *ts) | ||
508 | { | ||
509 | long now = ts->tv_sec; | ||
510 | |||
511 | if (time_status & STA_INS) { | ||
512 | time_state = TIME_INS; | ||
513 | now += 86400 - now % 86400; | ||
514 | hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | ||
515 | |||
516 | return; | ||
517 | } | ||
518 | |||
519 | if (time_status & STA_DEL) { | ||
520 | time_state = TIME_DEL; | ||
521 | now += 86400 - (now + 1) % 86400; | ||
522 | hrtimer_start(&leap_timer, ktime_set(now, 0), HRTIMER_MODE_ABS); | ||
523 | } | ||
524 | } | ||
525 | 539 | ||
526 | /* | 540 | /* |
527 | * Propagate a new txc->status value into the NTP state: | 541 | * Propagate a new txc->status value into the NTP state: |
@@ -546,22 +560,6 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts) | |||
546 | time_status &= STA_RONLY; | 560 | time_status &= STA_RONLY; |
547 | time_status |= txc->status & ~STA_RONLY; | 561 | time_status |= txc->status & ~STA_RONLY; |
548 | 562 | ||
549 | switch (time_state) { | ||
550 | case TIME_OK: | ||
551 | ntp_start_leap_timer(ts); | ||
552 | break; | ||
553 | case TIME_INS: | ||
554 | case TIME_DEL: | ||
555 | time_state = TIME_OK; | ||
556 | ntp_start_leap_timer(ts); | ||
557 | case TIME_WAIT: | ||
558 | if (!(time_status & (STA_INS | STA_DEL))) | ||
559 | time_state = TIME_OK; | ||
560 | break; | ||
561 | case TIME_OOP: | ||
562 | hrtimer_restart(&leap_timer); | ||
563 | break; | ||
564 | } | ||
565 | } | 563 | } |
566 | /* | 564 | /* |
567 | * Called with the xtime lock held, so we can access and modify | 565 | * Called with the xtime lock held, so we can access and modify |
@@ -643,9 +641,6 @@ int do_adjtimex(struct timex *txc) | |||
643 | (txc->tick < 900000/USER_HZ || | 641 | (txc->tick < 900000/USER_HZ || |
644 | txc->tick > 1100000/USER_HZ)) | 642 | txc->tick > 1100000/USER_HZ)) |
645 | return -EINVAL; | 643 | return -EINVAL; |
646 | |||
647 | if (txc->modes & ADJ_STATUS && time_state != TIME_OK) | ||
648 | hrtimer_cancel(&leap_timer); | ||
649 | } | 644 | } |
650 | 645 | ||
651 | if (txc->modes & ADJ_SETOFFSET) { | 646 | if (txc->modes & ADJ_SETOFFSET) { |
@@ -663,7 +658,7 @@ int do_adjtimex(struct timex *txc) | |||
663 | 658 | ||
664 | getnstimeofday(&ts); | 659 | getnstimeofday(&ts); |
665 | 660 | ||
666 | write_seqlock_irq(&xtime_lock); | 661 | spin_lock_irq(&ntp_lock); |
667 | 662 | ||
668 | if (txc->modes & ADJ_ADJTIME) { | 663 | if (txc->modes & ADJ_ADJTIME) { |
669 | long save_adjust = time_adjust; | 664 | long save_adjust = time_adjust; |
@@ -705,7 +700,7 @@ int do_adjtimex(struct timex *txc) | |||
705 | /* fill PPS status fields */ | 700 | /* fill PPS status fields */ |
706 | pps_fill_timex(txc); | 701 | pps_fill_timex(txc); |
707 | 702 | ||
708 | write_sequnlock_irq(&xtime_lock); | 703 | spin_unlock_irq(&ntp_lock); |
709 | 704 | ||
710 | txc->time.tv_sec = ts.tv_sec; | 705 | txc->time.tv_sec = ts.tv_sec; |
711 | txc->time.tv_usec = ts.tv_nsec; | 706 | txc->time.tv_usec = ts.tv_nsec; |
@@ -903,7 +898,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
903 | 898 | ||
904 | pts_norm = pps_normalize_ts(*phase_ts); | 899 | pts_norm = pps_normalize_ts(*phase_ts); |
905 | 900 | ||
906 | write_seqlock_irqsave(&xtime_lock, flags); | 901 | spin_lock_irqsave(&ntp_lock, flags); |
907 | 902 | ||
908 | /* clear the error bits, they will be set again if needed */ | 903 | /* clear the error bits, they will be set again if needed */ |
909 | time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); | 904 | time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); |
@@ -916,7 +911,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
916 | * just start the frequency interval */ | 911 | * just start the frequency interval */ |
917 | if (unlikely(pps_fbase.tv_sec == 0)) { | 912 | if (unlikely(pps_fbase.tv_sec == 0)) { |
918 | pps_fbase = *raw_ts; | 913 | pps_fbase = *raw_ts; |
919 | write_sequnlock_irqrestore(&xtime_lock, flags); | 914 | spin_unlock_irqrestore(&ntp_lock, flags); |
920 | return; | 915 | return; |
921 | } | 916 | } |
922 | 917 | ||
@@ -931,7 +926,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
931 | time_status |= STA_PPSJITTER; | 926 | time_status |= STA_PPSJITTER; |
932 | /* restart the frequency calibration interval */ | 927 | /* restart the frequency calibration interval */ |
933 | pps_fbase = *raw_ts; | 928 | pps_fbase = *raw_ts; |
934 | write_sequnlock_irqrestore(&xtime_lock, flags); | 929 | spin_unlock_irqrestore(&ntp_lock, flags); |
935 | pr_err("hardpps: PPSJITTER: bad pulse\n"); | 930 | pr_err("hardpps: PPSJITTER: bad pulse\n"); |
936 | return; | 931 | return; |
937 | } | 932 | } |
@@ -948,7 +943,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
948 | 943 | ||
949 | hardpps_update_phase(pts_norm.nsec); | 944 | hardpps_update_phase(pts_norm.nsec); |
950 | 945 | ||
951 | write_sequnlock_irqrestore(&xtime_lock, flags); | 946 | spin_unlock_irqrestore(&ntp_lock, flags); |
952 | } | 947 | } |
953 | EXPORT_SYMBOL(hardpps); | 948 | EXPORT_SYMBOL(hardpps); |
954 | 949 | ||
@@ -967,6 +962,4 @@ __setup("ntp_tick_adj=", ntp_tick_adj_setup); | |||
967 | void __init ntp_init(void) | 962 | void __init ntp_init(void) |
968 | { | 963 | { |
969 | ntp_clear(); | 964 | ntp_clear(); |
970 | hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
971 | leap_timer.function = ntp_leap_second; | ||
972 | } | 965 | } |