From: Harlan Stenn Date: Sat, 18 Sep 2010 22:40:06 +0000 (-0400) Subject: Initial convergence improvements from Dave Mills X-Git-Tag: NTP_4_2_7P52~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41a793ea2250b82de99c3e2f0f945a11539e1b3a;p=thirdparty%2Fntp.git Initial convergence improvements from Dave Mills bk: 4c953fc6T9jGogTiqdQrWz1p8k1jUg --- diff --git a/ChangeLog b/ChangeLog index 3c04dfef5..6de42e73f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* Initial convergence improvements from Dave Mills. (4.2.7p51) 2010/09/18 Released by Harlan Stenn * [Bug 1344] from 4.2.6p3-RC1: ntpd on Windows exits without logging cause. diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index fa4495615..fc2ce43c1 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -31,7 +31,7 @@ * All units are in s and s/s, unless noted otherwise. */ #define CLOCK_MAX .128 /* default step threshold (s) */ -#define CLOCK_MINSTEP 900. /* default stepout threshold (s) */ +#define CLOCK_MINSTEP 300. /* default stepout threshold (s) */ #define CLOCK_PANIC 1000. /* default panic threshold (s) */ #define CLOCK_PHI 15e-6 /* max frequency error (s/s) */ #define CLOCK_PLL 16. /* PLL loop gain (log2) */ @@ -142,6 +142,7 @@ int ext_enable; /* external clock enabled */ int pps_stratum; /* pps stratum */ int allow_panic = FALSE; /* allow panic correction */ int mode_ntpdate = FALSE; /* exit on first clock set */ +int freqcnt; /* initial frequency clamp */ /* * Clock state machine variables @@ -421,24 +422,26 @@ local_clock( /* * In FSET state this is the first update received and * the frequency has been initialized. Adjust the phase, - * but do not adjust the frequency until the next - * update. + * but do not adjust the frequency until the holdoff + * counter decrements to zero. */ case EVNT_FSET: + freqcnt = clock_minstep; rstclock(EVNT_SYNC, fp_offset); break; /* * In FREQ state ignore updates until the stepout * threshold. After that, compute the new frequency, but - * do not adjust the phase or frequency until the next - * update. + * do not adjust the frequency until the holdoff counter + * decrements to zero. */ case EVNT_FREQ: if (mu < clock_minstep) return (0); clock_frequency = direct_freq(fp_offset); + freqcnt = clock_minstep; rstclock(EVNT_SYNC, 0); break; @@ -446,34 +449,37 @@ local_clock( /* * We get here by default in SYNC and SPIK states. Here * we compute the frequency update due to PLL and FLL - * contributions. + * contributions. Note, we avoid frequency discipline at + * startup until the initial transient has subsided. */ default: allow_panic = FALSE; - - /* - * The FLL and PLL frequency gain constants - * depend on the time constant and Allan - * intercept. The PLL is always used, but - * becomes ineffective above the Allan intercept - * where the FLL becomes effective. - */ - if (sys_poll >= allan_xpt) - clock_frequency += (fp_offset - - clock_offset) / - max(ULOGTOD(sys_poll), mu) * - CLOCK_FLL; - - /* - * The PLL frequency gain (numerator) depends on - * the minimum of the update interval and Allan - * intercept. This reduces the PLL gain when the - * FLL becomes effective. - */ - etemp = min(ULOGTOD(allan_xpt), mu); - dtemp = 4 * CLOCK_PLL * ULOGTOD(sys_poll); - clock_frequency += fp_offset * etemp / (dtemp * - dtemp); + if (freqcnt == 0) { + + /* + * The FLL and PLL frequency gain constants + * depend on the time constant and Allan + * intercept. The PLL is always used, but + * becomes ineffective above the Allan intercept + * where the FLL becomes effective. + */ + if (sys_poll >= allan_xpt) + clock_frequency += (fp_offset - + clock_offset) / + max(ULOGTOD(sys_poll), mu) * + CLOCK_FLL; + + /* + * The PLL frequency gain (numerator) depends on + * the minimum of the update interval and Allan + * intercept. This reduces the PLL gain when the + * FLL becomes effective. + */ + etemp = min(ULOGTOD(allan_xpt), mu); + dtemp = 4 * CLOCK_PLL * ULOGTOD(sys_poll); + clock_frequency += fp_offset * etemp / (dtemp * + dtemp); + } rstclock(EVNT_SYNC, fp_offset); break; } @@ -495,7 +501,7 @@ local_clock( * lead to overflow problems. This might occur if some misguided * lad set the step threshold to something ridiculous. */ - if (pll_control && kern_enable) { + if (pll_control && kern_enable && freqcnt == 0) { /* * We initialize the structure for the ntp_adjtime() @@ -629,9 +635,12 @@ local_clock( * offset with the clock jitter. If the offset is less than the * clock jitter times a constant, then the averaging interval is * increased, otherwise it is decreased. A bit of hysteresis - * helps calm the dance. Works best using burst mode. + * helps calm the dance. Works best using burst mode. Don't + * fiddle with the poll during the startup clamp period. */ - if (fabs(clock_offset) < CLOCK_PGATE * clock_jitter) { + if (freqcnt > 0) { + tc_counter = 0; + } else if (fabs(clock_offset) < CLOCK_PGATE * clock_jitter) { tc_counter += sys_poll; if (tc_counter > CLOCK_LIMIT) { tc_counter = CLOCK_LIMIT; @@ -692,9 +701,12 @@ adj_host_clock( * NTPv3, NTPv4 does not declare unsynchronized after one day, * since the dispersion check serves this function. Also, * since the poll interval can exceed one day, the old test - * would be counterproductive. + * would be counterproductive. During the startup clamp period, the + * time constant is clamkped at 2. */ sys_rootdisp += clock_phi; + if (freqcnt > 0) + freqcnt--; #ifndef LOCKCLOCK /* @@ -702,15 +714,19 @@ adj_host_clock( * get out of Dodge quick. */ if (!ntp_enable || mode_ntpdate || (pll_control && - kern_enable)) + kern_enable && freqcnt == 0)) return; /* * Implement the phase and frequency adjustments. The gain * factor (denominator) increases with poll interval, so is - * dominated by the FLL above the Allan intercept. + * dominated by the FLL above the Allan intercept. Note the + * reduced time constant at startup. */ - adjustment = clock_offset / (CLOCK_PLL * ULOGTOD(sys_poll)); + if (freqcnt > 0) + adjustment = clock_offset / (CLOCK_PLL * 4); + else + adjustment = clock_offset / (CLOCK_PLL * ULOGTOD(sys_poll)); clock_offset -= adjustment; adj_systime(adjustment + drift_comp); #endif /* LOCKCLOCK */ @@ -755,23 +771,6 @@ direct_freq( double fp_offset ) { - -#ifdef KERNEL_PLL - /* - * If the kernel is enabled, we need the residual offset to - * calculate the frequency correction. - */ - if (pll_control && kern_enable) { - memset(&ntv, 0, sizeof(ntv)); - ntp_adjtime(&ntv); -#ifdef STA_NANO - clock_offset = ntv.offset / 1e9; -#else /* STA_NANO */ - clock_offset = ntv.offset / 1e6; -#endif /* STA_NANO */ - drift_comp = FREQTOD(ntv.freq); - } -#endif /* KERNEL_PLL */ set_freq((fp_offset - clock_offset) / (current_time - clock_epoch) + drift_comp); wander_resid = 0;