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; |