aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-12-09 21:07:37 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-11 17:34:52 -0500
commit9f8681db961de6d75e43844e9664f1f81e05e1b7 (patch)
tree07679d0ea408127119bc8b2ce74b38031da204e5 /net/dccp/ccids
parentde553c189e3faa0d0c38f366f73379b46587b80e (diff)
[DCCP] ccid3: Shift window counter computation
This puts the window counter computation [RFC 4342, 8.1] into a separate function which is called whenever a new packet is ready for immediate transmission in ccid3_hc_tx_send_packet. Justification: The window counter update was previously computed after the packet was sent. This has two drawbacks, both fixed by this patch: 1) re-compute another timestamp almost directly after the packet was sent (expensive), 2) the CCVal for the window counter is needed at the instant the packet is sent. Further details: The initialisation of the window counter is left in the state NO_SENT, as before. The algorithm will do nothing if either RTT is initialised to 0 (which is ok) or if the RTT value remains below 4 microseconds (which is almost pathological). Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r--net/dccp/ccids/ccid3.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 122a716eb877..1a2ffa1d8794 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -161,6 +161,33 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
161 */ 161 */
162} 162}
163 163
164/*
165 * Update Window Counter using the algorithm from [RFC 4342, 8.1].
166 * The algorithm is not applicable if RTT < 4 microseconds.
167 */
168static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
169 struct timeval *now)
170{
171 suseconds_t delta;
172 u32 quarter_rtts;
173
174 if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */
175 return;
176
177 delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count);
178 DCCP_BUG_ON(delta < 0);
179
180 quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);
181
182 if (quarter_rtts > 0) {
183 hctx->ccid3hctx_t_last_win_count = *now;
184 hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5);
185 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */
186
187 ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
188 }
189}
190
164static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 191static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
165{ 192{
166 struct sock *sk = (struct sock *)data; 193 struct sock *sk = (struct sock *)data;
@@ -333,6 +360,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
333 */ 360 */
334 if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0) 361 if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
335 return delay / 1000L; 362 return delay / 1000L;
363
364 ccid3_hc_tx_update_win_count(hctx, &now);
336 break; 365 break;
337 case TFRC_SSTATE_TERM: 366 case TFRC_SSTATE_TERM:
338 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk); 367 DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
@@ -353,7 +382,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
353 const struct dccp_sock *dp = dccp_sk(sk); 382 const struct dccp_sock *dp = dccp_sk(sk);
354 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 383 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
355 struct timeval now; 384 struct timeval now;
356 suseconds_t quarter_rtt;
357 struct dccp_tx_hist_entry *packet; 385 struct dccp_tx_hist_entry *packet;
358 386
359 BUG_ON(hctx == NULL); 387 BUG_ON(hctx == NULL);
@@ -373,25 +401,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
373 } 401 }
374 packet->dccphtx_tstamp = now; 402 packet->dccphtx_tstamp = now;
375 packet->dccphtx_seqno = dp->dccps_gss; 403 packet->dccphtx_seqno = dp->dccps_gss;
376 /*
377 * Check if win_count have changed
378 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
379 */
380 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
381 if (likely(hctx->ccid3hctx_rtt > 8))
382 quarter_rtt /= hctx->ccid3hctx_rtt / 4;
383
384 if (quarter_rtt > 0) {
385 hctx->ccid3hctx_t_last_win_count = now;
386 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
387 min_t(unsigned long, quarter_rtt, 5)) % 16;
388 ccid3_pr_debug("%s, sk=%p, window changed from "
389 "%u to %u!\n",
390 dccp_role(sk), sk,
391 packet->dccphtx_ccval,
392 hctx->ccid3hctx_last_win_count);
393 }
394
395 hctx->ccid3hctx_idle = 0; 404 hctx->ccid3hctx_idle = 0;
396 packet->dccphtx_rtt = hctx->ccid3hctx_rtt; 405 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
397 packet->dccphtx_sent = 1; 406 packet->dccphtx_sent = 1;