aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2011-11-14 16:48:36 -0500
committerJohn Stultz <john.stultz@linaro.org>2012-01-26 22:44:25 -0500
commitbd3312681f69207a40431981c1bce1afdc9b7975 (patch)
treead95aba265a7e6033e81cbc9b3054fac176ab6ce /kernel/time
parentea7cf49a7633c2b70125f59b4e3553d9181cb15d (diff)
ntp: Add ntp_lock to replace xtime_locking
Use a ntp_lock spin lock to replace xtime_lock locking in ntp.c CC: Thomas Gleixner <tglx@linutronix.de> CC: Eric Dumazet <eric.dumazet@gmail.com> CC: Richard Cochran <richardcochran@gmail.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/ntp.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index f131ba62da62..17fb1b9807d0 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -22,6 +22,9 @@
22 * NTP timekeeping variables: 22 * NTP timekeeping variables:
23 */ 23 */
24 24
25DEFINE_SPINLOCK(ntp_lock);
26
27
25/* USER_HZ period (usecs): */ 28/* USER_HZ period (usecs): */
26unsigned long tick_usec = TICK_USEC; 29unsigned long tick_usec = TICK_USEC;
27 30
@@ -133,7 +136,7 @@ static inline void pps_reset_freq_interval(void)
133/** 136/**
134 * pps_clear - Clears the PPS state variables 137 * pps_clear - Clears the PPS state variables
135 * 138 *
136 * Must be called while holding a write on the xtime_lock 139 * Must be called while holding a write on the ntp_lock
137 */ 140 */
138static inline void pps_clear(void) 141static inline void pps_clear(void)
139{ 142{
@@ -149,7 +152,7 @@ static inline void pps_clear(void)
149 * the last PPS signal. When it reaches 0, indicate that PPS signal is 152 * the last PPS signal. When it reaches 0, indicate that PPS signal is
150 * missing. 153 * missing.
151 * 154 *
152 * Must be called while holding a write on the xtime_lock 155 * Must be called while holding a write on the ntp_lock
153 */ 156 */
154static inline void pps_dec_valid(void) 157static inline void pps_dec_valid(void)
155{ 158{
@@ -341,11 +344,13 @@ static void ntp_update_offset(long offset)
341 344
342/** 345/**
343 * ntp_clear - Clears the NTP state variables 346 * ntp_clear - Clears the NTP state variables
344 *
345 * Must be called while holding a write on the xtime_lock
346 */ 347 */
347void ntp_clear(void) 348void ntp_clear(void)
348{ 349{
350 unsigned long flags;
351
352 spin_lock_irqsave(&ntp_lock, flags);
353
349 time_adjust = 0; /* stop active adjtime() */ 354 time_adjust = 0; /* stop active adjtime() */
350 time_status |= STA_UNSYNC; 355 time_status |= STA_UNSYNC;
351 time_maxerror = NTP_PHASE_LIMIT; 356 time_maxerror = NTP_PHASE_LIMIT;
@@ -358,12 +363,20 @@ void ntp_clear(void)
358 363
359 /* Clear PPS state variables */ 364 /* Clear PPS state variables */
360 pps_clear(); 365 pps_clear();
366 spin_unlock_irqrestore(&ntp_lock, flags);
367
361} 368}
362 369
363 370
364u64 ntp_tick_length(void) 371u64 ntp_tick_length(void)
365{ 372{
366 return tick_length; 373 unsigned long flags;
374 s64 ret;
375
376 spin_lock_irqsave(&ntp_lock, flags);
377 ret = tick_length;
378 spin_unlock_irqrestore(&ntp_lock, flags);
379 return ret;
367} 380}
368 381
369 382
@@ -375,14 +388,15 @@ u64 ntp_tick_length(void)
375static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) 388static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
376{ 389{
377 enum hrtimer_restart res = HRTIMER_NORESTART; 390 enum hrtimer_restart res = HRTIMER_NORESTART;
391 unsigned long flags;
392 int leap = 0;
378 393
379 write_seqlock(&xtime_lock); 394 spin_lock_irqsave(&ntp_lock, flags);
380
381 switch (time_state) { 395 switch (time_state) {
382 case TIME_OK: 396 case TIME_OK:
383 break; 397 break;
384 case TIME_INS: 398 case TIME_INS:
385 timekeeping_leap_insert(-1); 399 leap = -1;
386 time_state = TIME_OOP; 400 time_state = TIME_OOP;
387 printk(KERN_NOTICE 401 printk(KERN_NOTICE
388 "Clock: inserting leap second 23:59:60 UTC\n"); 402 "Clock: inserting leap second 23:59:60 UTC\n");
@@ -390,7 +404,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
390 res = HRTIMER_RESTART; 404 res = HRTIMER_RESTART;
391 break; 405 break;
392 case TIME_DEL: 406 case TIME_DEL:
393 timekeeping_leap_insert(1); 407 leap = 1;
394 time_tai--; 408 time_tai--;
395 time_state = TIME_WAIT; 409 time_state = TIME_WAIT;
396 printk(KERN_NOTICE 410 printk(KERN_NOTICE
@@ -405,8 +419,14 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
405 time_state = TIME_OK; 419 time_state = TIME_OK;
406 break; 420 break;
407 } 421 }
422 spin_unlock_irqrestore(&ntp_lock, flags);
408 423
409 write_sequnlock(&xtime_lock); 424 /*
425 * We have to call this outside of the ntp_lock to keep
426 * the proper locking hierarchy
427 */
428 if (leap)
429 timekeeping_leap_insert(leap);
410 430
411 return res; 431 return res;
412} 432}
@@ -422,6 +442,9 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
422void second_overflow(void) 442void second_overflow(void)
423{ 443{
424 s64 delta; 444 s64 delta;
445 unsigned long flags;
446
447 spin_lock_irqsave(&ntp_lock, flags);
425 448
426 /* Bump the maxerror field */ 449 /* Bump the maxerror field */
427 time_maxerror += MAXFREQ / NSEC_PER_USEC; 450 time_maxerror += MAXFREQ / NSEC_PER_USEC;
@@ -441,23 +464,25 @@ void second_overflow(void)
441 pps_dec_valid(); 464 pps_dec_valid();
442 465
443 if (!time_adjust) 466 if (!time_adjust)
444 return; 467 goto out;
445 468
446 if (time_adjust > MAX_TICKADJ) { 469 if (time_adjust > MAX_TICKADJ) {
447 time_adjust -= MAX_TICKADJ; 470 time_adjust -= MAX_TICKADJ;
448 tick_length += MAX_TICKADJ_SCALED; 471 tick_length += MAX_TICKADJ_SCALED;
449 return; 472 goto out;
450 } 473 }
451 474
452 if (time_adjust < -MAX_TICKADJ) { 475 if (time_adjust < -MAX_TICKADJ) {
453 time_adjust += MAX_TICKADJ; 476 time_adjust += MAX_TICKADJ;
454 tick_length -= MAX_TICKADJ_SCALED; 477 tick_length -= MAX_TICKADJ_SCALED;
455 return; 478 goto out;
456 } 479 }
457 480
458 tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ) 481 tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ)
459 << NTP_SCALE_SHIFT; 482 << NTP_SCALE_SHIFT;
460 time_adjust = 0; 483 time_adjust = 0;
484out:
485 spin_unlock_irqrestore(&ntp_lock, flags);
461} 486}
462 487
463#ifdef CONFIG_GENERIC_CMOS_UPDATE 488#ifdef CONFIG_GENERIC_CMOS_UPDATE
@@ -681,7 +706,7 @@ int do_adjtimex(struct timex *txc)
681 706
682 getnstimeofday(&ts); 707 getnstimeofday(&ts);
683 708
684 write_seqlock_irq(&xtime_lock); 709 spin_lock_irq(&ntp_lock);
685 710
686 if (txc->modes & ADJ_ADJTIME) { 711 if (txc->modes & ADJ_ADJTIME) {
687 long save_adjust = time_adjust; 712 long save_adjust = time_adjust;
@@ -723,7 +748,7 @@ int do_adjtimex(struct timex *txc)
723 /* fill PPS status fields */ 748 /* fill PPS status fields */
724 pps_fill_timex(txc); 749 pps_fill_timex(txc);
725 750
726 write_sequnlock_irq(&xtime_lock); 751 spin_unlock_irq(&ntp_lock);
727 752
728 txc->time.tv_sec = ts.tv_sec; 753 txc->time.tv_sec = ts.tv_sec;
729 txc->time.tv_usec = ts.tv_nsec; 754 txc->time.tv_usec = ts.tv_nsec;
@@ -921,7 +946,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
921 946
922 pts_norm = pps_normalize_ts(*phase_ts); 947 pts_norm = pps_normalize_ts(*phase_ts);
923 948
924 write_seqlock_irqsave(&xtime_lock, flags); 949 spin_lock_irqsave(&ntp_lock, flags);
925 950
926 /* clear the error bits, they will be set again if needed */ 951 /* clear the error bits, they will be set again if needed */
927 time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); 952 time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR);
@@ -934,7 +959,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
934 * just start the frequency interval */ 959 * just start the frequency interval */
935 if (unlikely(pps_fbase.tv_sec == 0)) { 960 if (unlikely(pps_fbase.tv_sec == 0)) {
936 pps_fbase = *raw_ts; 961 pps_fbase = *raw_ts;
937 write_sequnlock_irqrestore(&xtime_lock, flags); 962 spin_unlock_irqrestore(&ntp_lock, flags);
938 return; 963 return;
939 } 964 }
940 965
@@ -949,7 +974,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
949 time_status |= STA_PPSJITTER; 974 time_status |= STA_PPSJITTER;
950 /* restart the frequency calibration interval */ 975 /* restart the frequency calibration interval */
951 pps_fbase = *raw_ts; 976 pps_fbase = *raw_ts;
952 write_sequnlock_irqrestore(&xtime_lock, flags); 977 spin_unlock_irqrestore(&ntp_lock, flags);
953 pr_err("hardpps: PPSJITTER: bad pulse\n"); 978 pr_err("hardpps: PPSJITTER: bad pulse\n");
954 return; 979 return;
955 } 980 }
@@ -966,7 +991,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
966 991
967 hardpps_update_phase(pts_norm.nsec); 992 hardpps_update_phase(pts_norm.nsec);
968 993
969 write_sequnlock_irqrestore(&xtime_lock, flags); 994 spin_unlock_irqrestore(&ntp_lock, flags);
970} 995}
971EXPORT_SYMBOL(hardpps); 996EXPORT_SYMBOL(hardpps);
972 997