diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-05 00:51:48 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-03-05 00:51:48 +0100 |
commit | 132b044f4b09cd9334718b3f58dbb498ca63f82e (patch) | |
tree | 3ca56d757348a0048d06c3c042f174c60bd8dcaf /networking/ntpd.c | |
parent | e8cfc3f693e8a0cbfc489564c76e00c074f63066 (diff) | |
download | busybox-w32-132b044f4b09cd9334718b3f58dbb498ca63f82e.tar.gz busybox-w32-132b044f4b09cd9334718b3f58dbb498ca63f82e.tar.bz2 busybox-w32-132b044f4b09cd9334718b3f58dbb498ca63f82e.zip |
ntpd: experimental code to correct frequency a bit more aggressively
function old new delta
update_local_clock 730 792 +62
recv_and_process_peer_pkt 850 835 -15
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/ntpd.c')
-rw-r--r-- | networking/ntpd.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c index ba666b513..b0bfe440f 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -138,6 +138,7 @@ | |||
138 | * by staying at smaller poll). | 138 | * by staying at smaller poll). |
139 | */ | 139 | */ |
140 | #define POLLADJ_GATE 4 | 140 | #define POLLADJ_GATE 4 |
141 | #define TIMECONST_HACK_GATE 2 | ||
141 | /* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ | 142 | /* Compromise Allan intercept (sec). doc uses 1500, std ntpd uses 512 */ |
142 | #define ALLAN 512 | 143 | #define ALLAN 512 |
143 | /* PLL loop gain */ | 144 | /* PLL loop gain */ |
@@ -339,6 +340,7 @@ struct globals { | |||
339 | double last_update_offset; // c.last | 340 | double last_update_offset; // c.last |
340 | double last_update_recv_time; // s.t | 341 | double last_update_recv_time; // s.t |
341 | double discipline_jitter; // c.jitter | 342 | double discipline_jitter; // c.jitter |
343 | double offset_to_jitter_ratio; | ||
342 | //double cluster_offset; // s.offset | 344 | //double cluster_offset; // s.offset |
343 | //double cluster_jitter; // s.jitter | 345 | //double cluster_jitter; // s.jitter |
344 | #if !USING_KERNEL_PLL_LOOP | 346 | #if !USING_KERNEL_PLL_LOOP |
@@ -1337,7 +1339,8 @@ update_local_clock(peer_t *p) | |||
1337 | return 1; /* "ok to increase poll interval" */ | 1339 | return 1; /* "ok to increase poll interval" */ |
1338 | } | 1340 | } |
1339 | #endif | 1341 | #endif |
1340 | set_new_values(STATE_SYNC, /*offset:*/ 0, recv_time); | 1342 | offset = 0; |
1343 | set_new_values(STATE_SYNC, offset, recv_time); | ||
1341 | 1344 | ||
1342 | } else { /* abs_offset <= STEP_THRESHOLD */ | 1345 | } else { /* abs_offset <= STEP_THRESHOLD */ |
1343 | 1346 | ||
@@ -1355,6 +1358,7 @@ update_local_clock(peer_t *p) | |||
1355 | G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); | 1358 | G.discipline_jitter = SQRT(etemp + (dtemp - etemp) / AVG); |
1356 | if (G.discipline_jitter < G_precision_sec) | 1359 | if (G.discipline_jitter < G_precision_sec) |
1357 | G.discipline_jitter = G_precision_sec; | 1360 | G.discipline_jitter = G_precision_sec; |
1361 | G.offset_to_jitter_ratio = fabs(offset) / G.discipline_jitter; | ||
1358 | VERB3 bb_error_msg("discipline jitter=%f", G.discipline_jitter); | 1362 | VERB3 bb_error_msg("discipline jitter=%f", G.discipline_jitter); |
1359 | 1363 | ||
1360 | switch (G.discipline_state) { | 1364 | switch (G.discipline_state) { |
@@ -1443,7 +1447,7 @@ update_local_clock(peer_t *p) | |||
1443 | 1447 | ||
1444 | /* We are in STATE_SYNC now, but did not do adjtimex yet. | 1448 | /* We are in STATE_SYNC now, but did not do adjtimex yet. |
1445 | * (Any other state does not reach this, they all return earlier) | 1449 | * (Any other state does not reach this, they all return earlier) |
1446 | * By this time, freq_drift and G.last_update_offset are set | 1450 | * By this time, freq_drift and offset are set |
1447 | * to values suitable for adjtimex. | 1451 | * to values suitable for adjtimex. |
1448 | */ | 1452 | */ |
1449 | #if !USING_KERNEL_PLL_LOOP | 1453 | #if !USING_KERNEL_PLL_LOOP |
@@ -1482,40 +1486,42 @@ update_local_clock(peer_t *p) | |||
1482 | tmx.modes = ADJ_FREQUENCY | ADJ_OFFSET; | 1486 | tmx.modes = ADJ_FREQUENCY | ADJ_OFFSET; |
1483 | /* 65536 is one ppm */ | 1487 | /* 65536 is one ppm */ |
1484 | tmx.freq = G.discipline_freq_drift * 65536e6; | 1488 | tmx.freq = G.discipline_freq_drift * 65536e6; |
1485 | tmx.offset = G.last_update_offset * 1000000; /* usec */ | ||
1486 | #endif | 1489 | #endif |
1487 | tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; | 1490 | tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; |
1488 | tmx.offset = (G.last_update_offset * 1000000); /* usec */ | 1491 | tmx.offset = (offset * 1000000); /* usec */ |
1489 | /* + (G.last_update_offset < 0 ? -0.5 : 0.5) - too small to bother */ | ||
1490 | tmx.status = STA_PLL; | 1492 | tmx.status = STA_PLL; |
1491 | if (G.ntp_status & LI_PLUSSEC) | 1493 | if (G.ntp_status & LI_PLUSSEC) |
1492 | tmx.status |= STA_INS; | 1494 | tmx.status |= STA_INS; |
1493 | if (G.ntp_status & LI_MINUSSEC) | 1495 | if (G.ntp_status & LI_MINUSSEC) |
1494 | tmx.status |= STA_DEL; | 1496 | tmx.status |= STA_DEL; |
1497 | |||
1495 | tmx.constant = G.poll_exp - 4; | 1498 | tmx.constant = G.poll_exp - 4; |
1496 | //tmx.esterror = (u_int32)(clock_jitter * 1e6); | 1499 | /* EXPERIMENTAL. |
1497 | //tmx.maxerror = (u_int32)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); | 1500 | * The below if statement should be unnecessary, but... |
1501 | * It looks like Linux kernel's PLL is far too gentle in changing | ||
1502 | * tmx.freq in response to clock offset. Offset keeps growing | ||
1503 | * and eventually we fall back to smaller poll intervals. | ||
1504 | * We can make correction more agressive (about x2) by supplying | ||
1505 | * PLL time constant which is one less than the real one. | ||
1506 | * To be on a safe side, let's do it only if offset is significantly | ||
1507 | * larger than jitter. | ||
1508 | */ | ||
1509 | if (tmx.constant > 0 && G.offset_to_jitter_ratio > TIMECONST_HACK_GATE) | ||
1510 | tmx.constant--; | ||
1511 | |||
1512 | //tmx.esterror = (uint32_t)(clock_jitter * 1e6); | ||
1513 | //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); | ||
1498 | rc = adjtimex(&tmx); | 1514 | rc = adjtimex(&tmx); |
1499 | if (rc < 0) | 1515 | if (rc < 0) |
1500 | bb_perror_msg_and_die("adjtimex"); | 1516 | bb_perror_msg_and_die("adjtimex"); |
1501 | /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4. | 1517 | /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4. |
1502 | * Not sure why. Perhaps it is normal. | 1518 | * Not sure why. Perhaps it is normal. |
1503 | */ | 1519 | */ |
1504 | VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld constant:%ld status:0x%x", | 1520 | VERB3 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", |
1505 | rc, tmx.freq, tmx.offset, tmx.constant, tmx.status); | 1521 | rc, tmx.freq, tmx.offset, tmx.status); |
1506 | #if 0 | ||
1507 | VERB3 { | ||
1508 | /* always gives the same output as above msg */ | ||
1509 | memset(&tmx, 0, sizeof(tmx)); | ||
1510 | if (adjtimex(&tmx) < 0) | ||
1511 | bb_perror_msg_and_die("adjtimex"); | ||
1512 | VERB3 bb_error_msg("c adjtimex freq:%ld offset:%+ld constant:%ld status:0x%x", | ||
1513 | tmx.freq, tmx.offset, tmx.constant, tmx.status); | ||
1514 | } | ||
1515 | #endif | ||
1516 | G.kernel_freq_drift = tmx.freq / 65536; | 1522 | G.kernel_freq_drift = tmx.freq / 65536; |
1517 | VERB2 bb_error_msg("update peer:%s, offset:%+f, jitter:%f, clock drift:%+.3f ppm", | 1523 | VERB2 bb_error_msg("update peer:%s, offset:%+f, jitter:%f, clock drift:%+.3f ppm, tc:%d", |
1518 | p->p_dotted, G.last_update_offset, G.discipline_jitter, (double)tmx.freq / 65536); | 1524 | p->p_dotted, offset, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant); |
1519 | 1525 | ||
1520 | return 1; /* "ok to increase poll interval" */ | 1526 | return 1; /* "ok to increase poll interval" */ |
1521 | } | 1527 | } |
@@ -1651,7 +1657,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1651 | if (!p->reachable_bits) { | 1657 | if (!p->reachable_bits) { |
1652 | /* 1st datapoint ever - replicate offset in every element */ | 1658 | /* 1st datapoint ever - replicate offset in every element */ |
1653 | int i; | 1659 | int i; |
1654 | for (i = 1; i < NUM_DATAPOINTS; i++) { | 1660 | for (i = 0; i < NUM_DATAPOINTS; i++) { |
1655 | p->filter_datapoint[i].d_offset = datapoint->d_offset; | 1661 | p->filter_datapoint[i].d_offset = datapoint->d_offset; |
1656 | } | 1662 | } |
1657 | } | 1663 | } |
@@ -1706,7 +1712,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1706 | ? "grows" : "falls" | 1712 | ? "grows" : "falls" |
1707 | ); | 1713 | ); |
1708 | } | 1714 | } |
1709 | if (rc > 0 && fabs(q->filter_offset) < POLLADJ_GATE * G.discipline_jitter) { | 1715 | if (rc > 0 && G.offset_to_jitter_ratio < POLLADJ_GATE) { |
1710 | /* was += G.poll_exp but it is a bit | 1716 | /* was += G.poll_exp but it is a bit |
1711 | * too optimistic for my taste at high poll_exp's */ | 1717 | * too optimistic for my taste at high poll_exp's */ |
1712 | G.polladj_count += MINPOLL; | 1718 | G.polladj_count += MINPOLL; |