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 /kernel/time | |
| 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>
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/ntp.c | 64 |
1 files changed, 16 insertions, 48 deletions
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; |
