diff options
-rw-r--r-- | include/linux/timex.h | 11 | ||||
-rw-r--r-- | kernel/time/ntp.c | 51 |
2 files changed, 24 insertions, 38 deletions
diff --git a/include/linux/timex.h b/include/linux/timex.h index 671609ee1a3d..ac808f13fa0e 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -69,10 +69,9 @@ | |||
69 | * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, | 69 | * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, |
70 | * respectively. | 70 | * respectively. |
71 | */ | 71 | */ |
72 | #define SHIFT_KG 6 /* phase factor (shift) */ | 72 | #define SHIFT_PLL 4 /* PLL frequency factor (shift) */ |
73 | #define SHIFT_KF 16 /* PLL frequency factor (shift) */ | 73 | #define SHIFT_FLL 2 /* FLL frequency factor (shift) */ |
74 | #define SHIFT_KH 2 /* FLL frequency factor (shift) */ | 74 | #define MAXTC 10 /* maximum time constant (shift) */ |
75 | #define MAXTC 6 /* maximum time constant (shift) */ | ||
76 | 75 | ||
77 | /* | 76 | /* |
78 | * The SHIFT_SCALE define establishes the decimal point of the time_phase | 77 | * The SHIFT_SCALE define establishes the decimal point of the time_phase |
@@ -97,8 +96,8 @@ | |||
97 | #define MAXPHASE 512000L /* max phase error (us) */ | 96 | #define MAXPHASE 512000L /* max phase error (us) */ |
98 | #define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */ | 97 | #define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */ |
99 | #define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */ | 98 | #define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */ |
100 | #define MINSEC 16L /* min interval between updates (s) */ | 99 | #define MINSEC 256 /* min interval between updates (s) */ |
101 | #define MAXSEC 1200L /* max interval between updates (s) */ | 100 | #define MAXSEC 2048 /* max interval between updates (s) */ |
102 | #define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */ | 101 | #define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */ |
103 | 102 | ||
104 | /* | 103 | /* |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 9137b54613e0..1ab5e9d7fa50 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -145,18 +145,11 @@ void second_overflow(void) | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * Compute the phase adjustment for the next second. In PLL mode, the | 148 | * Compute the phase adjustment for the next second. The offset is |
149 | * offset is reduced by a fixed factor times the time constant. In FLL | 149 | * reduced by a fixed factor times the time constant. |
150 | * mode the offset is used directly. In either mode, the maximum phase | ||
151 | * adjustment for each second is clamped so as to spread the adjustment | ||
152 | * over not more than the number of seconds between updates. | ||
153 | */ | 150 | */ |
154 | tick_length = tick_length_base; | 151 | tick_length = tick_length_base; |
155 | time_adj = time_offset; | 152 | time_adj = shift_right(time_offset, SHIFT_PLL + time_constant); |
156 | if (!(time_status & STA_FLL)) | ||
157 | time_adj = shift_right(time_adj, SHIFT_KG + time_constant); | ||
158 | time_adj = min(time_adj, -((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC); | ||
159 | time_adj = max(time_adj, ((MAXPHASE / HZ) << SHIFT_UPDATE) / MINSEC); | ||
160 | time_offset -= time_adj; | 153 | time_offset -= time_adj; |
161 | tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE); | 154 | tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE); |
162 | 155 | ||
@@ -200,7 +193,7 @@ void __attribute__ ((weak)) notify_arch_cmos_timer(void) | |||
200 | int do_adjtimex(struct timex *txc) | 193 | int do_adjtimex(struct timex *txc) |
201 | { | 194 | { |
202 | long ltemp, mtemp, save_adjust; | 195 | long ltemp, mtemp, save_adjust; |
203 | s64 freq_adj; | 196 | s64 freq_adj, temp64; |
204 | int result; | 197 | int result; |
205 | 198 | ||
206 | /* In order to modify anything, you gotta be super-user! */ | 199 | /* In order to modify anything, you gotta be super-user! */ |
@@ -270,7 +263,7 @@ int do_adjtimex(struct timex *txc) | |||
270 | result = -EINVAL; | 263 | result = -EINVAL; |
271 | goto leave; | 264 | goto leave; |
272 | } | 265 | } |
273 | time_constant = txc->constant; | 266 | time_constant = min(txc->constant + 4, (long)MAXTC); |
274 | } | 267 | } |
275 | 268 | ||
276 | if (txc->modes & ADJ_OFFSET) { /* values checked earlier */ | 269 | if (txc->modes & ADJ_OFFSET) { /* values checked earlier */ |
@@ -298,26 +291,20 @@ int do_adjtimex(struct timex *txc) | |||
298 | time_reftime = xtime.tv_sec; | 291 | time_reftime = xtime.tv_sec; |
299 | mtemp = xtime.tv_sec - time_reftime; | 292 | mtemp = xtime.tv_sec - time_reftime; |
300 | time_reftime = xtime.tv_sec; | 293 | time_reftime = xtime.tv_sec; |
301 | freq_adj = 0; | 294 | |
302 | if (time_status & STA_FLL) { | 295 | freq_adj = (s64)time_offset * mtemp; |
303 | if (mtemp >= MINSEC) { | 296 | freq_adj = shift_right(freq_adj, time_constant * 2 + |
304 | freq_adj = (s64)time_offset << (SHIFT_NSEC - SHIFT_KH); | 297 | (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); |
305 | if (time_offset < 0) { | 298 | if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { |
306 | freq_adj = -freq_adj; | 299 | temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL); |
307 | do_div(freq_adj, mtemp); | 300 | if (time_offset < 0) { |
308 | freq_adj = -freq_adj; | 301 | temp64 = -temp64; |
309 | } else | 302 | do_div(temp64, mtemp); |
310 | do_div(freq_adj, mtemp); | 303 | freq_adj -= temp64; |
311 | } else /* calibration interval too short (p. 12) */ | 304 | } else { |
312 | result = TIME_ERROR; | 305 | do_div(temp64, mtemp); |
313 | } else { /* PLL mode */ | 306 | freq_adj += temp64; |
314 | if (mtemp < MAXSEC) { | 307 | } |
315 | freq_adj = (s64)ltemp * mtemp; | ||
316 | freq_adj = shift_right(freq_adj,(time_constant + | ||
317 | time_constant + | ||
318 | SHIFT_KF - SHIFT_NSEC)); | ||
319 | } else /* calibration interval too long (p. 12) */ | ||
320 | result = TIME_ERROR; | ||
321 | } | 308 | } |
322 | freq_adj += time_freq; | 309 | freq_adj += time_freq; |
323 | freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); | 310 | freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); |