dntpd - Improve offset correction precision
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 15 Mar 2014 16:28:55 +0000 (09:28 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 15 Mar 2014 16:28:55 +0000 (09:28 -0700)
* Offset corrections are more accurate with more samples (whereas frequency
  corrections are more accurate when the first and last sample are far apart
  in the time domain).

* Even though dntpd uses a standard deviation test to conditionalize offset
  corrections, it is still possible to get false positives with only 4
  samples.

* Once dntpd has gone into maintainance mode increase the number of
  required samples for an offset correction from 4 to 8.  This makes
  the standard deviation more accurate, reduces false positives, and
  improves stability.

* Retain the original mechanic during aquisition so dntpd applies corrections
  sooner rather than later when first started.

usr.sbin/dntpd/client.c

index ae5a9a8..2de4865 100644 (file)
@@ -265,6 +265,7 @@ client_check(struct server_info **checkp,
 {
     struct server_info *check = *checkp;
     struct server_info *info;
+    int min_samples;
 
     /*
      * Start an alternate linear regression once our current one
@@ -304,6 +305,9 @@ client_check(struct server_info **checkp,
     /*
      * BEST CLIENT FOR FREQUENCY CORRECTION:
      *
+     * Frequency corrections get better the longer the time separation
+     * between samples.
+     *
      * 8 samples and a correlation > 0.99, or
      * 16 samples and a correlation > 0.96
      */
@@ -327,10 +331,18 @@ client_check(struct server_info **checkp,
      * offset correction is valid if the standard deviation is less then
      * the average offset divided by 4.
      *
+     * If we are in maintainance mode, require 8 samples instead of 4.
+     * Offset corrections get better with more samples.  This reduces
+     * ping-pong effects that can occur with a small number of samples.
+     *
      * Servers marked as being insane are not allowed
      */
     info = *best_off;
-    if (check->lin_countoffset >= 4 && 
+    if (info && info->poll_mode == POLL_MAINTAIN)
+       min_samples = 8;
+    else
+       min_samples = 4;
+    if (check->lin_countoffset >= min_samples &&
        (check->lin_cache_stddev <
         fabs(check->lin_sumoffset / check->lin_countoffset / 4)) &&
        check->server_insane == 0