conf: add option to set maximum slew rate

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.
This commit is contained in:
Miroslav Lichvar 2014-05-21 16:23:30 +02:00
parent 3e1dc801b0
commit 9cf78b974a
4 changed files with 44 additions and 9 deletions

View 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

11
conf.c
View file

@ -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)
{

1
conf.h
View file

@ -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);

View 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,