]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
conf: add option to set maximum slew rate
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 21 May 2014 14:23:30 +0000 (16:23 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 22 May 2014 11:28:46 +0000 (13:28 +0200)
With the generic driver, the maxslewrate directive sets the maximum
frequency offset that the driver is allowed to use to slew the time. By
default, it's set to 83333.333 (1/12). This is identical to what Linux
fast slewing used to use.

chrony.texi.in
conf.c
conf.h
sys_generic.c

index eee4b845b656f2cbb09e5c1ea3e53c084f7041f5..63de048fbe2cf4fbdaa99b5fe8c9263d73b70a95 100644 (file)
@@ -1155,6 +1155,7 @@ the configuration file is ignored.
 * maxchange directive::         Set maximum allowed offset
 * maxclockerror directive::     Set maximum frequency error of local clock
 * maxsamples directive::        Set maximum number of samples per source
+* maxslewrate directive::       Set maximum slew rate
 * maxupdateskew directive::     Stop bad estimates upsetting machine clock
 * minsamples directive::        Set minimum number of samples per source
 * noclientlog directive::       Prevent chronyd from gathering data about clients
@@ -1536,8 +1537,10 @@ The syntax is
 corrtimeratio 100
 @end example
 
-The current remaining correction is shown in the @code{tracking} report
-(@pxref{tracking command}) as the @code{System time} value.
+The maximum allowed slew rate can be set by the @code{maxslewrate}
+directive (@pxref{maxslewrate directive}.  The current remaining
+correction is shown in the @code{tracking} report (@pxref{tracking
+command}) as the @code{System time} value.
 @c }}}
 @c {{{ deny
 @node deny directive
@@ -2398,6 +2401,23 @@ The syntax is
 maxsamples <samples>
 @end example
 @c }}}
+@c {{{ maxslewrate
+@node maxslewrate directive
+@subsection maxslewrate
+The @code{maxslewrate} directive sets the maximum rate at which @code{chronyd}
+is allowed to slew the time.  It limits the slew rate controlled by the
+correction time ratio (@pxref{corrtimeratio directive}) and is effective
+only on systems where @code{chronyd} is able to control the rate (so
+far only Linux).
+
+By default, the maximum slew rate is 83333.333 ppm (one twelfth).
+
+The syntax is
+
+@example
+maxslewrate <rate-in-ppm>
+@end example
+@c }}}
 @c {{{ maxupdateskew
 @node maxupdateskew directive
 @subsection maxupdateskew
diff --git a/conf.c b/conf.c
index 5e419d4588fc5cab3271292bceb933cbc3ca976c..26fd6050ca311a71595fbdf70ae9f17ddb46c441 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -88,6 +88,7 @@ static unsigned long command_key_id;
 static double max_update_skew = 1000.0;
 static double correction_time_ratio = 3.0;
 static double max_clock_error = 1.0; /* in ppm */
+static double max_slew_rate = 1e6 / 12.0; /* in ppm */
 
 static double reselect_distance = 1e-4;
 static double stratum_weight = 1.0;
@@ -422,6 +423,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
     parse_double(p, &max_clock_error);
   } else if (!strcasecmp(command, "maxsamples")) {
     parse_int(p, &max_samples);
+  } else if (!strcasecmp(command, "maxslewrate")) {
+    parse_double(p, &max_slew_rate);
   } else if (!strcasecmp(command, "maxupdateskew")) {
     parse_double(p, &max_update_skew);
   } else if (!strcasecmp(command, "minsamples")) {
@@ -1390,6 +1393,14 @@ CNF_GetCorrectionTimeRatio(void)
 
 /* ================================================== */
 
+double
+CNF_GetMaxSlewRate(void)
+{
+  return max_slew_rate;
+}
+
+/* ================================================== */
+
 double
 CNF_GetReselectDistance(void)
 {
diff --git a/conf.h b/conf.h
index 2ee9a006b3557836168b8a9f1c36e1de1eafbd7d..7b98bcf89f9d10f027b7a69a67caadac8606e068 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -81,6 +81,7 @@ extern void CNF_GetLinuxFreqScale(int *set, double *freq_scale);
 extern double CNF_GetMaxUpdateSkew(void);
 extern double CNF_GetMaxClockError(void);
 extern double CNF_GetCorrectionTimeRatio(void);
+extern double CNF_GetMaxSlewRate(void);
 
 extern double CNF_GetReselectDistance(void);
 extern double CNF_GetStratumWeight(void);
index d6c109d859587a16711ed968f20bb33cdebe4eeb..62a5a7cf6f10c7a0ad46dbfeddeace8c8832c10a 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "sys_generic.h"
 
+#include "conf.h"
 #include "local.h"
 #include "localp.h"
 #include "logging.h"
@@ -52,6 +53,9 @@ static double max_freq;
    in local time */
 static double max_freq_change_delay;
 
+/* Maximum allowed frequency offset relative to the base frequency */
+static double max_corr_freq;
+
 /* Amount of outstanding offset to process */
 static double offset_register;
 
@@ -62,9 +66,6 @@ static double offset_register;
    as set by drv_set_freq (not in ppm) */
 static double slew_freq;
 
-/* Maximum allowed slewing frequency */
-#define MAX_SLEW_FREQ (1 / 12.0)
-
 /* Time (raw) of last update of slewing frequency and offset */
 static struct timeval slew_start;
 
@@ -129,10 +130,10 @@ update_slew(void)
   /* Get frequency offset needed to slew the offset in the duration
      and clamp it to the allowed maximum */
   corr_freq = offset_register / duration;
-  if (corr_freq < -MAX_SLEW_FREQ)
-    corr_freq = -MAX_SLEW_FREQ;
-  else if (corr_freq > MAX_SLEW_FREQ)
-    corr_freq = MAX_SLEW_FREQ;
+  if (corr_freq < -max_corr_freq)
+    corr_freq = -max_corr_freq;
+  else if (corr_freq > max_corr_freq)
+    corr_freq = max_corr_freq;
 
   /* Get the new real frequency and clamp it */
   total_freq = base_freq + corr_freq * (1.0e6 - base_freq);
@@ -275,6 +276,8 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela
   slew_freq = 0.0;
   offset_register = 0.0;
 
+  max_corr_freq = CNF_GetMaxSlewRate() / 1.0e6;
+
   lcl_RegisterSystemDrivers(read_frequency, set_frequency,
                             accrue_offset, sys_apply_step_offset ?
                               sys_apply_step_offset : apply_step_offset,