diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2014-09-27 22:56:09 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-09-27 22:56:09 +0200 |
commit | d3fe9602714e01b228fa0c625901e748912a7775 (patch) | |
tree | da2169608d86f751ab4bc1b48263d9a832cffa06 | |
parent | 186b98a86f069bb65bf4110e324d75fef98857c0 (diff) | |
download | busybox-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.c | 80 |
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 | ||
983 | static 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 | */ |
1656 | static unsigned | 1672 | static unsigned |
1657 | retry_interval(void) | 1673 | poll_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 | } | ||
1667 | static unsigned | ||
1668 | poll_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 | } |
1681 | static NOINLINE void | 1685 | static 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 | } |