* 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
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
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
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;
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")) {
/* ================================================== */
+double
+CNF_GetMaxSlewRate(void)
+{
+ return max_slew_rate;
+}
+
+/* ================================================== */
+
double
CNF_GetReselectDistance(void)
{
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);
#include "sys_generic.h"
+#include "conf.h"
#include "local.h"
#include "localp.h"
#include "logging.h"
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;
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;
/* 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);
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,