]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Initial convergence improvements from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Sat, 18 Sep 2010 22:40:06 +0000 (18:40 -0400)
committerHarlan Stenn <stenn@ntp.org>
Sat, 18 Sep 2010 22:40:06 +0000 (18:40 -0400)
bk: 4c953fc6T9jGogTiqdQrWz1p8k1jUg

ChangeLog
ntpd/ntp_loopfilter.c

index 3c04dfef5a5277c2afce6340dbc9a6fc19d2f44d..6de42e73ffeefb48f0d46ea4360fe0fa14cfdbf0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* Initial convergence improvements from Dave Mills.
 (4.2.7p51) 2010/09/18 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 1344] from 4.2.6p3-RC1: ntpd on Windows exits without logging
   cause.
index fa44956158944098c2ec79599436eb0250e6e893..fc2ce43c183d61ec7a0c6c09108f69092ac70bc0 100644 (file)
@@ -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;