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/time | |
| 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/time')
| -rw-r--r-- | kernel/time/ntp.c | 50 |
1 files changed, 44 insertions, 6 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; |
