diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2006-10-01 02:28:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-01 03:39:26 -0400 |
commit | 3d3675cc3d04d7fd4bb11e8c1ea79e5ade4f5e44 (patch) | |
tree | 7beeef2896cb92e06b0a2ee8fa62b17f1732b72b | |
parent | dc6a43e46f1b6de22701f97bec022e97088cfa90 (diff) |
[PATCH] ntp: prescale time_offset
This converts time_offset into a scaled per tick value. This avoids now
completely the crude compensation in second_overflow().
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 | 2 | ||||
-rw-r--r-- | kernel/time/ntp.c | 64 |
2 files changed, 17 insertions, 49 deletions
diff --git a/include/linux/timex.h b/include/linux/timex.h index b589c8218bb9..1cde6f6a2712 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -89,7 +89,7 @@ | |||
89 | * FINENSEC is 1 ns in SHIFT_UPDATE units of the time_phase variable. | 89 | * FINENSEC is 1 ns in SHIFT_UPDATE units of the time_phase variable. |
90 | */ | 90 | */ |
91 | #define SHIFT_SCALE 22 /* phase scale (shift) */ | 91 | #define SHIFT_SCALE 22 /* phase scale (shift) */ |
92 | #define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */ | 92 | #define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */ |
93 | #define SHIFT_USEC 16 /* frequency offset scale (shift) */ | 93 | #define SHIFT_USEC 16 /* frequency offset scale (shift) */ |
94 | #define FINENSEC (1L << (SHIFT_SCALE - 10)) /* ~1 ns in phase units */ | 94 | #define FINENSEC (1L << (SHIFT_SCALE - 10)) /* ~1 ns in phase units */ |
95 | 95 | ||
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index ab21eb06e09b..238ce47ef09d 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -31,7 +31,7 @@ int tickadj = 500/HZ ? : 1; /* microsecs */ | |||
31 | /* TIME_ERROR prevents overwriting the CMOS clock */ | 31 | /* TIME_ERROR prevents overwriting the CMOS clock */ |
32 | int time_state = TIME_OK; /* clock synchronization status */ | 32 | int time_state = TIME_OK; /* clock synchronization status */ |
33 | int time_status = STA_UNSYNC; /* clock status bits */ | 33 | int time_status = STA_UNSYNC; /* clock status bits */ |
34 | long time_offset; /* time adjustment (us) */ | 34 | long time_offset; /* time adjustment (ns) */ |
35 | long time_constant = 2; /* pll time constant */ | 35 | long time_constant = 2; /* pll time constant */ |
36 | long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */ | 36 | long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */ |
37 | long time_precision = 1; /* clock precision (us) */ | 37 | long time_precision = 1; /* clock precision (us) */ |
@@ -57,6 +57,7 @@ void ntp_clear(void) | |||
57 | ntp_update_frequency(); | 57 | ntp_update_frequency(); |
58 | 58 | ||
59 | tick_length = tick_length_base; | 59 | tick_length = tick_length_base; |
60 | time_offset = 0; | ||
60 | } | 61 | } |
61 | 62 | ||
62 | #define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE) | 63 | #define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE) |
@@ -83,7 +84,7 @@ void ntp_update_frequency(void) | |||
83 | */ | 84 | */ |
84 | void second_overflow(void) | 85 | void second_overflow(void) |
85 | { | 86 | { |
86 | long ltemp, time_adj; | 87 | long time_adj; |
87 | 88 | ||
88 | /* Bump the maxerror field */ | 89 | /* Bump the maxerror field */ |
89 | time_maxerror += time_tolerance >> SHIFT_USEC; | 90 | time_maxerror += time_tolerance >> SHIFT_USEC; |
@@ -151,42 +152,14 @@ void second_overflow(void) | |||
151 | * adjustment for each second is clamped so as to spread the adjustment | 152 | * adjustment for each second is clamped so as to spread the adjustment |
152 | * over not more than the number of seconds between updates. | 153 | * over not more than the number of seconds between updates. |
153 | */ | 154 | */ |
154 | ltemp = time_offset; | ||
155 | if (!(time_status & STA_FLL)) | ||
156 | ltemp = shift_right(ltemp, SHIFT_KG + time_constant); | ||
157 | ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE); | ||
158 | ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE); | ||
159 | time_offset -= ltemp; | ||
160 | time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE); | ||
161 | |||
162 | /* | ||
163 | * Compute the frequency estimate and additional phase adjustment due | ||
164 | * to frequency error for the next second. | ||
165 | */ | ||
166 | |||
167 | #if HZ == 100 | ||
168 | /* | ||
169 | * Compensate for (HZ==100) != (1 << SHIFT_HZ). Add 25% and 3.125% to | ||
170 | * get 128.125; => only 0.125% error (p. 14) | ||
171 | */ | ||
172 | time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5); | ||
173 | #endif | ||
174 | #if HZ == 250 | ||
175 | /* | ||
176 | * Compensate for (HZ==250) != (1 << SHIFT_HZ). Add 1.5625% and | ||
177 | * 0.78125% to get 255.85938; => only 0.05% error (p. 14) | ||
178 | */ | ||
179 | time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); | ||
180 | #endif | ||
181 | #if HZ == 1000 | ||
182 | /* | ||
183 | * Compensate for (HZ==1000) != (1 << SHIFT_HZ). Add 1.5625% and | ||
184 | * 0.78125% to get 1023.4375; => only 0.05% error (p. 14) | ||
185 | */ | ||
186 | time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7); | ||
187 | #endif | ||
188 | tick_length = tick_length_base; | 155 | tick_length = tick_length_base; |
189 | tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - (SHIFT_SCALE - 10)); | 156 | time_adj = time_offset; |
157 | if (!(time_status & STA_FLL)) | ||
158 | time_adj = shift_right(time_adj, SHIFT_KG + time_constant); | ||
159 | time_adj = min(time_adj, -((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC); | ||
160 | time_adj = max(time_adj, ((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC); | ||
161 | time_offset -= time_adj; | ||
162 | tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE); | ||
190 | } | 163 | } |
191 | 164 | ||
192 | /* | 165 | /* |
@@ -347,12 +320,8 @@ int do_adjtimex(struct timex *txc) | |||
347 | * Scale the phase adjustment and | 320 | * Scale the phase adjustment and |
348 | * clamp to the operating range. | 321 | * clamp to the operating range. |
349 | */ | 322 | */ |
350 | if (ltemp > MAXPHASE) | 323 | time_offset = min(ltemp, MAXPHASE); |
351 | time_offset = MAXPHASE << SHIFT_UPDATE; | 324 | time_offset = max(time_offset, -MAXPHASE); |
352 | else if (ltemp < -MAXPHASE) | ||
353 | time_offset = -(MAXPHASE << SHIFT_UPDATE); | ||
354 | else | ||
355 | time_offset = ltemp << SHIFT_UPDATE; | ||
356 | 325 | ||
357 | /* | 326 | /* |
358 | * Select whether the frequency is to be controlled | 327 | * Select whether the frequency is to be controlled |
@@ -366,8 +335,7 @@ int do_adjtimex(struct timex *txc) | |||
366 | time_reftime = xtime.tv_sec; | 335 | time_reftime = xtime.tv_sec; |
367 | if (time_status & STA_FLL) { | 336 | if (time_status & STA_FLL) { |
368 | if (mtemp >= MINSEC) { | 337 | if (mtemp >= MINSEC) { |
369 | ltemp = (time_offset / mtemp) << (SHIFT_USEC - | 338 | ltemp = ((time_offset << 12) / mtemp) << (SHIFT_USEC - 12); |
370 | SHIFT_UPDATE); | ||
371 | time_freq += shift_right(ltemp, SHIFT_KH); | 339 | time_freq += shift_right(ltemp, SHIFT_KH); |
372 | } else /* calibration interval too short (p. 12) */ | 340 | } else /* calibration interval too short (p. 12) */ |
373 | result = TIME_ERROR; | 341 | result = TIME_ERROR; |
@@ -382,6 +350,7 @@ int do_adjtimex(struct timex *txc) | |||
382 | } | 350 | } |
383 | time_freq = min(time_freq, time_tolerance); | 351 | time_freq = min(time_freq, time_tolerance); |
384 | time_freq = max(time_freq, -time_tolerance); | 352 | time_freq = max(time_freq, -time_tolerance); |
353 | time_offset = (time_offset * NSEC_PER_USEC / HZ) << SHIFT_UPDATE; | ||
385 | } /* STA_PLL */ | 354 | } /* STA_PLL */ |
386 | } /* txc->modes & ADJ_OFFSET */ | 355 | } /* txc->modes & ADJ_OFFSET */ |
387 | if (txc->modes & ADJ_TICK) | 356 | if (txc->modes & ADJ_TICK) |
@@ -395,9 +364,8 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) | |||
395 | 364 | ||
396 | if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) | 365 | if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) |
397 | txc->offset = save_adjust; | 366 | txc->offset = save_adjust; |
398 | else { | 367 | else |
399 | txc->offset = shift_right(time_offset, SHIFT_UPDATE); | 368 | txc->offset = shift_right(time_offset, SHIFT_UPDATE) * HZ / 1000; |
400 | } | ||
401 | txc->freq = time_freq; | 369 | txc->freq = time_freq; |
402 | txc->maxerror = time_maxerror; | 370 | txc->maxerror = time_maxerror; |
403 | txc->esterror = time_esterror; | 371 | txc->esterror = time_esterror; |