aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/ntpd.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 1c0063ef7..d4754f8ba 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -43,13 +43,13 @@
43 * max 5 is very talkative (and bloated). 2 is non-bloated, 43 * max 5 is very talkative (and bloated). 2 is non-bloated,
44 * production level setting. 44 * production level setting.
45 */ 45 */
46#define MAX_VERBOSE 2 46#define MAX_VERBOSE 2
47 47
48 48
49#define RETRY_INTERVAL 5 /* on error, retry in N secs */ 49#define RETRY_INTERVAL 5 /* on error, retry in N secs */
50#define QUERYTIME_MAX 15 /* wait for reply up to N secs */ 50#define QUERYTIME_MAX 15 /* wait for reply up to N secs */
51 51
52#define FREQ_TOLERANCE 15e-6 /* % frequency tolerance (15 PPM) */ 52#define FREQ_TOLERANCE 0.000015 /* % frequency tolerance (15 PPM) */
53#define MINPOLL 4 /* % minimum poll interval (6: 64 s) */ 53#define MINPOLL 4 /* % minimum poll interval (6: 64 s) */
54#define MAXPOLL 12 /* % maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */ 54#define MAXPOLL 12 /* % maximum poll interval (12: 1.1h, 17: 36.4h) (was 17) */
55#define MINDISP 0.01 /* % minimum dispersion (s) */ 55#define MINDISP 0.01 /* % minimum dispersion (s) */
@@ -59,34 +59,35 @@
59#define MIN_SELECTED 1 /* % minimum intersection survivors */ 59#define MIN_SELECTED 1 /* % minimum intersection survivors */
60#define MIN_CLUSTERED 3 /* % minimum cluster survivors */ 60#define MIN_CLUSTERED 3 /* % minimum cluster survivors */
61 61
62#define MAXFREQ 0.000500 /* frequency tolerance (500 PPM) */ 62#define MAXDRIFT 0.000500 /* frequency drift we can correct (500 PPM) */
63 63
64/* Clock discipline parameters and constants */ 64/* Clock discipline parameters and constants */
65#define STEP_THRESHOLD 0.128 /* step threshold (s) */ 65#define STEP_THRESHOLD 0.128 /* step threshold (s) */
66#define WATCH_THRESHOLD 150 /* stepout threshold (s). std ntpd uses 900 (11 mins (!)) */ 66#define WATCH_THRESHOLD 150 /* stepout threshold (s). std ntpd uses 900 (11 mins (!)) */
67/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ 67/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */
68#define PANIC_THRESHOLD 1000 /* panic threshold (s) */ 68#define PANIC_THRESHOLD 1000 /* panic threshold (s) */
69 69
70/* Poll-adjust threshold. 70/* Poll-adjust threshold.
71 * When we see that offset is small enough compared to discipline jitter, 71 * When we see that offset is small enough compared to discipline jitter,
72 * we grow a counter: += MINPOLL. When it goes over POLLADJ_LIMIT, 72 * we grow a counter: += MINPOLL. When it goes over POLLADJ_LIMIT,
73 * we poll_ext++. If offset isn't small, counter -= poll_ext*2, 73 * we poll_exp++. If offset isn't small, counter -= poll_exp*2,
74 * and when it goes below -POLLADJ_LIMIT, we poll_ext-- 74 * and when it goes below -POLLADJ_LIMIT, we poll_exp--
75 */ 75 */
76#define POLLADJ_LIMIT 30 76#define POLLADJ_LIMIT 30
77/* If offset < POLLADJ_GATE * discipline_jitter, then we can increase 77/* If offset < POLLADJ_GATE * discipline_jitter, then we can increase
78 * poll interval (we think we can't improve timekeeping 78 * poll interval (we think we can't improve timekeeping
79 * by staying at smaller poll). 79 * by staying at smaller poll).
80 */ 80 */
81#define POLLADJ_GATE 4 81#define POLLADJ_GATE 4
82/* Compromise Allan intercept (s). doc uses 1500, std ntpd uses 512 */ 82/* Compromise Allan intercept (s). doc uses 1500, std ntpd uses 512 */
83#define ALLAN 512 83#define ALLAN 512
84/* PLL loop gain */ 84/* PLL loop gain */
85#define PLL 65536 85#define PLL 65536
86/* FLL loop gain [why it depends on MAXPOLL??] */ 86/* FLL loop gain [why it depends on MAXPOLL??] */
87#define FLL (MAXPOLL + 1) 87#define FLL (MAXPOLL + 1)
88/* Parameter averaging constant */ 88/* Parameter averaging constant */
89#define AVG 4 89#define AVG 4
90
90 91
91enum { 92enum {
92 NTP_VERSION = 4, 93 NTP_VERSION = 4,
@@ -251,13 +252,17 @@ struct globals {
251 uint8_t discipline_state; // doc calls it c.state 252 uint8_t discipline_state; // doc calls it c.state
252 uint8_t poll_exp; // s.poll 253 uint8_t poll_exp; // s.poll
253 int polladj_count; // c.count 254 int polladj_count; // c.count
254 double discipline_jitter; // c.jitter 255 long kernel_freq_drift;
255 double last_update_offset; // c.last 256 double last_update_offset; // c.last
257 double last_update_recv_time; // s.t
258 double discipline_jitter; // c.jitter
259//TODO: add s.jitter - grep for it here and see clock_combine() in doc
260#define USING_KERNEL_PLL_LOOP 1
261#if !USING_KERNEL_PLL_LOOP
256 double discipline_freq_drift; // c.freq 262 double discipline_freq_drift; // c.freq
257//TODO: conditionally calculate wander? it's used only for logging 263//TODO: conditionally calculate wander? it's used only for logging
258 double discipline_wander; // c.wander 264 double discipline_wander; // c.wander
259 double last_update_recv_time; // s.t 265#endif
260//TODO: add s.jitter - grep for it here and see clock_combine() in doc
261}; 266};
262#define G (*ptr_to_globals) 267#define G (*ptr_to_globals)
263 268
@@ -1153,25 +1158,27 @@ update_local_clock(peer_t *p, double t)
1153 * (Any other state does not reach this, they all return earlier) 1158 * (Any other state does not reach this, they all return earlier)
1154 * By this time, freq_drift and G.last_update_offset are set 1159 * By this time, freq_drift and G.last_update_offset are set
1155 * to values suitable for adjtimex. 1160 * to values suitable for adjtimex.
1156 * 1161 */
1157 * Calculate the new frequency drift and frequency stability (wander). 1162#if !USING_KERNEL_PLL_LOOP
1163 /* Calculate the new frequency drift and frequency stability (wander).
1158 * Compute the clock wander as the RMS of exponentially weighted 1164 * Compute the clock wander as the RMS of exponentially weighted
1159 * frequency differences. This is not used directly, but can, 1165 * frequency differences. This is not used directly, but can,
1160 * along with the jitter, be a highly useful monitoring and 1166 * along with the jitter, be a highly useful monitoring and
1161 * debugging tool. 1167 * debugging tool.
1162 */ 1168 */
1163 dtemp = G.discipline_freq_drift + freq_drift; 1169 dtemp = G.discipline_freq_drift + freq_drift;
1164 G.discipline_freq_drift = MAXD(MIND(MAXFREQ, dtemp), -MAXFREQ); 1170 G.discipline_freq_drift = MAXD(MIND(MAXDRIFT, dtemp), -MAXDRIFT);
1165 etemp = SQUARE(G.discipline_wander); 1171 etemp = SQUARE(G.discipline_wander);
1166 dtemp = SQUARE(dtemp); 1172 dtemp = SQUARE(dtemp);
1167 G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG); 1173 G.discipline_wander = SQRT(etemp + (dtemp - etemp) / AVG);
1168 1174
1175 VERB3 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",
1176 G.discipline_freq_drift,
1177 (long)(G.discipline_freq_drift * 65536e6),
1178 freq_drift,
1179 G.discipline_wander);
1180#endif
1169 VERB3 { 1181 VERB3 {
1170 bb_error_msg("discipline freq_drift=%.9f(int:%ld corr:%e) wander=%f",
1171 G.discipline_freq_drift,
1172 (long)(G.discipline_freq_drift * 65536e6),
1173 freq_drift,
1174 G.discipline_wander);
1175 memset(&tmx, 0, sizeof(tmx)); 1182 memset(&tmx, 0, sizeof(tmx));
1176 if (adjtimex(&tmx) < 0) 1183 if (adjtimex(&tmx) < 0)
1177 bb_perror_msg_and_die("adjtimex"); 1184 bb_perror_msg_and_die("adjtimex");
@@ -1192,7 +1199,7 @@ update_local_clock(peer_t *p, double t)
1192 } 1199 }
1193 memset(&tmx, 0, sizeof(tmx)); 1200 memset(&tmx, 0, sizeof(tmx));
1194#if 0 1201#if 0
1195//doesn't work, offset remains 0 (!): 1202//doesn't work, offset remains 0 (!) in kernel:
1196//ntpd: set adjtimex freq:1786097 tmx.offset:77487 1203//ntpd: set adjtimex freq:1786097 tmx.offset:77487
1197//ntpd: prev adjtimex freq:1786097 tmx.offset:0 1204//ntpd: prev adjtimex freq:1786097 tmx.offset:0
1198//ntpd: cur adjtimex freq:1786097 tmx.offset:0 1205//ntpd: cur adjtimex freq:1786097 tmx.offset:0
@@ -1218,14 +1225,21 @@ update_local_clock(peer_t *p, double t)
1218 rc = adjtimex(&tmx); 1225 rc = adjtimex(&tmx);
1219 if (rc < 0) 1226 if (rc < 0)
1220 bb_perror_msg_and_die("adjtimex"); 1227 bb_perror_msg_and_die("adjtimex");
1228 if (G.kernel_freq_drift != tmx.freq / 65536) {
1229 G.kernel_freq_drift = tmx.freq / 65536;
1230 VERB2 bb_error_msg("kernel clock drift: %ld ppm", G.kernel_freq_drift);
1231 }
1221 VERB3 { 1232 VERB3 {
1222 bb_error_msg("adjtimex:%d freq:%ld offset:%ld constant:%ld status:0x%x", 1233 bb_error_msg("adjtimex:%d freq:%ld offset:%ld constant:%ld status:0x%x",
1223 rc, tmx.freq, tmx.offset, tmx.constant, tmx.status); 1234 rc, tmx.freq, tmx.offset, tmx.constant, tmx.status);
1235#if 0
1236 /* always gives the same output as above msg */
1224 memset(&tmx, 0, sizeof(tmx)); 1237 memset(&tmx, 0, sizeof(tmx));
1225 if (adjtimex(&tmx) < 0) 1238 if (adjtimex(&tmx) < 0)
1226 bb_perror_msg_and_die("adjtimex"); 1239 bb_perror_msg_and_die("adjtimex");
1227 VERB3 bb_error_msg("c adjtimex freq:%ld offset:%ld constant:%ld status:0x%x", 1240 VERB3 bb_error_msg("c adjtimex freq:%ld offset:%ld constant:%ld status:0x%x",
1228 tmx.freq, tmx.offset, tmx.constant, tmx.status); 1241 tmx.freq, tmx.offset, tmx.constant, tmx.status);
1242#endif
1229 } 1243 }
1230// #define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ - ? 1244// #define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ - ?
1231// it appeared after a while: 1245// it appeared after a while: