diff options
| author | Roman Zippel <zippel@linux-m68k.org> | 2006-10-01 02:28:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-01 03:39:26 -0400 |
| commit | b0ee75561beadc4db4d9a899c8ef4a7db50aa0ab (patch) | |
| tree | e50354c74ce17f6ea78dc1d7fac608788de517f3 /kernel | |
| parent | 4c7ee8de956fc250fe31e2fa91f6da980fabe317 (diff) | |
[PATCH] ntp: add ntp_update_frequency
This introduces ntp_update_frequency() and deinlines ntp_clear() (as it's not
performance critical). ntp_update_frequency() calculates the base tick length
using tick_usec and adds a base adjustment, in case the frequency doesn't
divide evenly by HZ.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Cc: john stultz <johnstul@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/time/ntp.c | 50 | ||||
| -rw-r--r-- | kernel/timer.c | 11 |
2 files changed, 48 insertions, 13 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 8ccce15b4b23..77137bec2aea 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
| @@ -15,6 +15,13 @@ | |||
| 15 | #include <asm/div64.h> | 15 | #include <asm/div64.h> |
| 16 | #include <asm/timex.h> | 16 | #include <asm/timex.h> |
| 17 | 17 | ||
| 18 | /* | ||
| 19 | * Timekeeping variables | ||
| 20 | */ | ||
| 21 | unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */ | ||
| 22 | unsigned long tick_nsec; /* ACTHZ period (nsec) */ | ||
| 23 | static u64 tick_length, tick_length_base; | ||
| 24 | |||
| 18 | /* Don't completely fail for HZ > 500. */ | 25 | /* Don't completely fail for HZ > 500. */ |
| 19 | int tickadj = 500/HZ ? : 1; /* microsecs */ | 26 | int tickadj = 500/HZ ? : 1; /* microsecs */ |
| 20 | 27 | ||
| @@ -37,6 +44,36 @@ long time_reftime; /* time at last adjustment (s) */ | |||
| 37 | long time_adjust; | 44 | long time_adjust; |
| 38 | long time_next_adjust; | 45 | long time_next_adjust; |
| 39 | 46 | ||
| 47 | /** | ||
| 48 | * ntp_clear - Clears the NTP state variables | ||
| 49 | * | ||
| 50 | * Must be called while holding a write on the xtime_lock | ||
| 51 | */ | ||
| 52 | void ntp_clear(void) | ||
| 53 | { | ||
| 54 | time_adjust = 0; /* stop active adjtime() */ | ||
| 55 | time_status |= STA_UNSYNC; | ||
| 56 | time_maxerror = NTP_PHASE_LIMIT; | ||
| 57 | time_esterror = NTP_PHASE_LIMIT; | ||
| 58 | |||
| 59 | ntp_update_frequency(); | ||
| 60 | |||
| 61 | tick_length = tick_length_base; | ||
| 62 | } | ||
| 63 | |||
| 64 | #define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE) | ||
| 65 | #define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / (s64)CLOCK_TICK_RATE) | ||
| 66 | |||
| 67 | void ntp_update_frequency(void) | ||
| 68 | { | ||
| 69 | tick_length_base = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT; | ||
| 70 | tick_length_base += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; | ||
| 71 | |||
| 72 | do_div(tick_length_base, HZ); | ||
| 73 | |||
| 74 | tick_nsec = tick_length_base >> TICK_LENGTH_SHIFT; | ||
| 75 | } | ||
| 76 | |||
| 40 | /* | 77 | /* |
| 41 | * this routine handles the overflow of the microsecond field | 78 | * this routine handles the overflow of the microsecond field |
| 42 | * | 79 | * |
| @@ -151,6 +188,7 @@ void second_overflow(void) | |||
| 151 | */ | 188 | */ |
| 152 | time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); | 189 | time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); |
| 153 | #endif | 190 | #endif |
| 191 | tick_length = tick_length_base; | ||
| 154 | } | 192 | } |
| 155 | 193 | ||
| 156 | /* | 194 | /* |
| @@ -204,14 +242,13 @@ void update_ntp_one_tick(void) | |||
| 204 | */ | 242 | */ |
| 205 | u64 current_tick_length(void) | 243 | u64 current_tick_length(void) |
| 206 | { | 244 | { |
| 207 | long delta_nsec; | ||
| 208 | u64 ret; | 245 | u64 ret; |
| 209 | 246 | ||
| 210 | /* calculate the finest interval NTP will allow. | 247 | /* calculate the finest interval NTP will allow. |
| 211 | * ie: nanosecond value shifted by (SHIFT_SCALE - 10) | 248 | * ie: nanosecond value shifted by (SHIFT_SCALE - 10) |
| 212 | */ | 249 | */ |
| 213 | delta_nsec = tick_nsec + adjtime_adjustment() * 1000; | 250 | ret = tick_length; |
| 214 | ret = (u64)delta_nsec << TICK_LENGTH_SHIFT; | 251 | ret += (u64)(adjtime_adjustment() * 1000) << TICK_LENGTH_SHIFT; |
| 215 | ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10)); | 252 | ret += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10)); |
| 216 | 253 | ||
| 217 | return ret; | 254 | return ret; |
| @@ -351,10 +388,11 @@ int do_adjtimex(struct timex *txc) | |||
| 351 | time_freq = max(time_freq, -time_tolerance); | 388 | time_freq = max(time_freq, -time_tolerance); |
| 352 | } /* STA_PLL */ | 389 | } /* STA_PLL */ |
| 353 | } /* txc->modes & ADJ_OFFSET */ | 390 | } /* txc->modes & ADJ_OFFSET */ |
| 354 | if (txc->modes & ADJ_TICK) { | 391 | if (txc->modes & ADJ_TICK) |
| 355 | tick_usec = txc->tick; | 392 | tick_usec = txc->tick; |
| 356 | tick_nsec = TICK_USEC_TO_NSEC(tick_usec); | 393 | |
| 357 | } | 394 | if (txc->modes & ADJ_TICK) |
| 395 | ntp_update_frequency(); | ||
| 358 | } /* txc->modes */ | 396 | } /* txc->modes */ |
| 359 | leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) | 397 | leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) |
| 360 | result = TIME_ERROR; | 398 | result = TIME_ERROR; |
diff --git a/kernel/timer.c b/kernel/timer.c index 5fccc7cbf3b4..78d3fa10fcd6 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -562,12 +562,6 @@ found: | |||
| 562 | 562 | ||
| 563 | /******************************************************************/ | 563 | /******************************************************************/ |
| 564 | 564 | ||
| 565 | /* | ||
| 566 | * Timekeeping variables | ||
| 567 | */ | ||
| 568 | unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */ | ||
| 569 | unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */ | ||
| 570 | |||
| 571 | /* | 565 | /* |
| 572 | * The current time | 566 | * The current time |
| 573 | * wall_to_monotonic is what we need to add to xtime (or xtime corrected | 567 | * wall_to_monotonic is what we need to add to xtime (or xtime corrected |
| @@ -757,10 +751,13 @@ void __init timekeeping_init(void) | |||
| 757 | unsigned long flags; | 751 | unsigned long flags; |
| 758 | 752 | ||
| 759 | write_seqlock_irqsave(&xtime_lock, flags); | 753 | write_seqlock_irqsave(&xtime_lock, flags); |
| 754 | |||
| 755 | ntp_clear(); | ||
| 756 | |||
| 760 | clock = clocksource_get_next(); | 757 | clock = clocksource_get_next(); |
| 761 | clocksource_calculate_interval(clock, tick_nsec); | 758 | clocksource_calculate_interval(clock, tick_nsec); |
| 762 | clock->cycle_last = clocksource_read(clock); | 759 | clock->cycle_last = clocksource_read(clock); |
| 763 | ntp_clear(); | 760 | |
| 764 | write_sequnlock_irqrestore(&xtime_lock, flags); | 761 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| 765 | } | 762 | } |
| 766 | 763 | ||
