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 | |
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>
-rw-r--r-- | include/linux/timex.h | 14 | ||||
-rw-r--r-- | kernel/time/ntp.c | 50 | ||||
-rw-r--r-- | kernel/timer.c | 11 |
3 files changed, 50 insertions, 25 deletions
diff --git a/include/linux/timex.h b/include/linux/timex.h index 2a21485bf183..b589c8218bb9 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -219,18 +219,8 @@ extern long time_reftime; /* time at last adjustment (s) */ | |||
219 | extern long time_adjust; /* The amount of adjtime left */ | 219 | extern long time_adjust; /* The amount of adjtime left */ |
220 | extern long time_next_adjust; /* Value for time_adjust at next tick */ | 220 | extern long time_next_adjust; /* Value for time_adjust at next tick */ |
221 | 221 | ||
222 | /** | 222 | extern void ntp_clear(void); |
223 | * ntp_clear - Clears the NTP state variables | 223 | extern void ntp_update_frequency(void); |
224 | * | ||
225 | * Must be called while holding a write on the xtime_lock | ||
226 | */ | ||
227 | static inline void ntp_clear(void) | ||
228 | { | ||
229 | time_adjust = 0; /* stop active adjtime() */ | ||
230 | time_status |= STA_UNSYNC; | ||
231 | time_maxerror = NTP_PHASE_LIMIT; | ||
232 | time_esterror = NTP_PHASE_LIMIT; | ||
233 | } | ||
234 | 224 | ||
235 | /** | 225 | /** |
236 | * ntp_synced - Returns 1 if the NTP status is not UNSYNC | 226 | * ntp_synced - Returns 1 if the NTP status is not UNSYNC |
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 | ||