aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-09-27 22:56:09 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-09-27 22:56:09 +0200
commitd3fe9602714e01b228fa0c625901e748912a7775 (patch)
treeda2169608d86f751ab4bc1b48263d9a832cffa06
parent186b98a86f069bb65bf4110e324d75fef98857c0 (diff)
downloadbusybox-w32-d3fe9602714e01b228fa0c625901e748912a7775.tar.gz
busybox-w32-d3fe9602714e01b228fa0c625901e748912a7775.tar.bz2
busybox-w32-d3fe9602714e01b228fa0c625901e748912a7775.zip
ntpd: be less eager to use shorter poll intervals
* on step, poll interval drops to 8.5 mins instead of 32 seconds * on total loss of all replies (no replies from any peer for last 8 requests), also drop poll interval to 8.5 mins instead of 32 seconds * on send abd recv errors, RETRY_INTERVAL is now 32 seconds, not 5 seconds * on timing out listening to reply, instead of unconditional shortening poll interval by x4, clamp it to NOREPLY_INTERVAL (512 seconds) * if a largish offset is seen, clamp nexp poll interval to 128 seconds, not 64 seconds function old new delta clamp_pollexp_and_set_MAXSTRAT - 37 +37 recv_and_process_peer_pkt 861 869 +8 poll_interval 52 48 -4 update_local_clock 762 752 -10 ntpd_main 1063 1050 -13 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/3 up/down: 45/-27) Total: 18 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ntpd.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 2d1ad69a0..b2b2791a8 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -109,35 +109,43 @@
109 * datapoints after the step. 109 * datapoints after the step.
110 */ 110 */
111 111
112#define RETRY_INTERVAL 5 /* on error, retry in N secs */
113#define RESPONSE_INTERVAL 15 /* wait for reply up to N secs */
114#define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 112#define INITIAL_SAMPLES 4 /* how many samples do we want for init */
115#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ 113#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */
116 114
117/* Clock discipline parameters and constants */ 115#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */
116#define NOREPLY_INTERVAL 512 /* sent, but got no reply: cap next query by this many seconds */
117#define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */
118 118
119/* Step threshold (sec). std ntpd uses 0.128. 119/* Step threshold (sec). std ntpd uses 0.128.
120 * Using exact power of 2 (1/8) results in smaller code */ 120 * Using exact power of 2 (1/8) results in smaller code
121 */
121#define STEP_THRESHOLD 0.125 122#define STEP_THRESHOLD 0.125
122#define WATCH_THRESHOLD 128 /* stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ 123/* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */
124#define WATCH_THRESHOLD 128
123/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ 125/* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */
124//UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ 126//UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */
125 127
128/*
129 * If we got |offset| > BIGOFF from a peer, cap next query interval
130 * for this peer by this many seconds:
131 */
132#define BIGOFF (STEP_THRESHOLD * 8)
133#define BIGOFF_INTERVAL (1 << 7) /* 128 s */
134
126#define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ 135#define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */
127#define BURSTPOLL 0 /* initial poll */ 136#define BURSTPOLL 0 /* initial poll */
128#define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */ 137#define MINPOLL 5 /* minimum poll interval. std ntpd uses 6 (6: 64 sec) */
129/* If we got largish offset from a peer, cap next query interval 138/*
130 * for this peer by this many seconds: 139 * If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL,
131 */
132#define BIGOFF_INTERVAL (1 << 6)
133/* If offset > discipline_jitter * POLLADJ_GATE, and poll interval is >= 2^BIGPOLL,
134 * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_). 140 * then it is decreased _at once_. (If < 2^BIGPOLL, it will be decreased _eventually_).
135 */ 141 */
136#define BIGPOLL 10 /* 2^10 sec ~= 17 min */ 142#define BIGPOLL 10 /* 2^10 sec ~= 17 min */
137#define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ 143#define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */
138/* Actively lower poll when we see such big offsets. 144/*
145 * Actively lower poll when we see such big offsets.
139 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively 146 * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively
140 * if offset increases over ~0.04 sec */ 147 * if offset increases over ~0.04 sec
148 */
141#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) 149#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3)
142#define MINDISP 0.01 /* minimum dispersion (sec) */ 150#define MINDISP 0.01 /* minimum dispersion (sec) */
143#define MAXDISP 16 /* maximum dispersion (sec) */ 151#define MAXDISP 16 /* maximum dispersion (sec) */
@@ -972,6 +980,16 @@ step_time(double offset)
972 } 980 }
973} 981}
974 982
983static void clamp_pollexp_and_set_MAXSTRAT(void)
984{
985 if (G.poll_exp < MINPOLL)
986 G.poll_exp = MINPOLL;
987 if (G.poll_exp >= BIGPOLL)
988 G.poll_exp = BIGPOLL - 1;
989 G.polladj_count = 0;
990 G.stratum = MAXSTRAT;
991}
992
975 993
976/* 994/*
977 * Selection and clustering, and their helpers 995 * Selection and clustering, and their helpers
@@ -1453,9 +1471,7 @@ update_local_clock(peer_t *p)
1453 exit(0); 1471 exit(0);
1454 } 1472 }
1455 1473
1456 G.polladj_count = 0; 1474 clamp_pollexp_and_set_MAXSTRAT();
1457 G.poll_exp = MINPOLL;
1458 G.stratum = MAXSTRAT;
1459 1475
1460 run_script("step", offset); 1476 run_script("step", offset);
1461 1477
@@ -1654,28 +1670,16 @@ update_local_clock(peer_t *p)
1654 * (helpers first) 1670 * (helpers first)
1655 */ 1671 */
1656static unsigned 1672static unsigned
1657retry_interval(void) 1673poll_interval(int upper_bound)
1658{
1659 /* Local problem, want to retry soon */
1660 unsigned interval, r;
1661 interval = RETRY_INTERVAL;
1662 r = rand();
1663 interval += r % (unsigned)(RETRY_INTERVAL / 4);
1664 VERB4 bb_error_msg("chose retry interval:%u", interval);
1665 return interval;
1666}
1667static unsigned
1668poll_interval(int exponent)
1669{ 1674{
1670 unsigned interval, r, mask; 1675 unsigned interval, r, mask;
1671 exponent = G.poll_exp + exponent; 1676 interval = 1 << G.poll_exp;
1672 if (exponent < 0) 1677 if (interval > upper_bound)
1673 exponent = 0; 1678 interval = upper_bound;
1674 interval = 1 << exponent;
1675 mask = ((interval-1) >> 4) | 1; 1679 mask = ((interval-1) >> 4) | 1;
1676 r = rand(); 1680 r = rand();
1677 interval += r & mask; /* ~ random(0..1) * interval/16 */ 1681 interval += r & mask; /* ~ random(0..1) * interval/16 */
1678 VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); 1682 VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d)", interval, G.poll_exp);
1679 return interval; 1683 return interval;
1680} 1684}
1681static NOINLINE void 1685static NOINLINE void
@@ -1741,7 +1745,7 @@ recv_and_process_peer_pkt(peer_t *p)
1741 || errno == EAGAIN 1745 || errno == EAGAIN
1742 ) { 1746 ) {
1743//TODO: always do this? 1747//TODO: always do this?
1744 interval = retry_interval(); 1748 interval = poll_interval(RETRY_INTERVAL);
1745 goto set_next_and_ret; 1749 goto set_next_and_ret;
1746 } 1750 }
1747 xfunc_die(); 1751 xfunc_die();
@@ -1897,8 +1901,8 @@ recv_and_process_peer_pkt(peer_t *p)
1897 1901
1898 /* Decide when to send new query for this peer */ 1902 /* Decide when to send new query for this peer */
1899 pick_normal_interval: 1903 pick_normal_interval:
1900 interval = poll_interval(0); 1904 interval = poll_interval(INT_MAX);
1901 if (fabs(offset) >= STEP_THRESHOLD * 8 && interval > BIGOFF_INTERVAL) { 1905 if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) {
1902 /* If we are synced, offsets are less than STEP_THRESHOLD, 1906 /* If we are synced, offsets are less than STEP_THRESHOLD,
1903 * or at the very least not much larger than it. 1907 * or at the very least not much larger than it.
1904 * Now we see a largish one. 1908 * Now we see a largish one.
@@ -2248,7 +2252,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2248 /* Timed out waiting for reply */ 2252 /* Timed out waiting for reply */
2249 close(p->p_fd); 2253 close(p->p_fd);
2250 p->p_fd = -1; 2254 p->p_fd = -1;
2251 timeout = poll_interval(-2); /* -2: try a bit sooner */ 2255 timeout = poll_interval(NOREPLY_INTERVAL);
2252 bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", 2256 bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us",
2253 p->p_dotted, p->reachable_bits, timeout); 2257 p->p_dotted, p->reachable_bits, timeout);
2254 set_next(p, timeout); 2258 set_next(p, timeout);
@@ -2339,9 +2343,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2339 goto have_reachable_peer; 2343 goto have_reachable_peer;
2340 } 2344 }
2341 /* No peer responded for last 8 packets, panic */ 2345 /* No peer responded for last 8 packets, panic */
2342 G.polladj_count = 0; 2346 clamp_pollexp_and_set_MAXSTRAT();
2343 G.poll_exp = MINPOLL;
2344 G.stratum = MAXSTRAT;
2345 run_script("unsync", 0.0); 2347 run_script("unsync", 0.0);
2346 have_reachable_peer: ; 2348 have_reachable_peer: ;
2347 } 2349 }