aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2007-12-17 09:57:43 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:58:23 -0500
commit52515e77a7a69867c479db4c9efb6be832b82179 (patch)
treed4246af065a53f7e2ae92070ec07d59ba892baf6 /net/dccp/ccids
parentd8d1252f744cb7cebd6ba3a4b7feec31ff23ccde (diff)
[CCID3]: Nofeedback timer according to rfc3448bis
This implements the changes to the nofeedback timer handling suggested in draft rfc3448bis00, section 4.4. In particular, these changes mean: * better handling of the lossless case (p == 0) * the timestamp for computing t_ld becomes obsolete * much more recent document (RFC 3448 is almost 5 years old) * concepts in rfc3448bis arose from a real, working implementation (cf. sec. 12) Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r--net/dccp/ccids/ccid3.c63
1 files changed, 29 insertions, 34 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 1156fef17471..d292f23c002e 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -131,12 +131,11 @@ static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
131 * 131 *
132 */ 132 */
133static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp) 133static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
134
135{ 134{
136 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 135 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
137 __u64 min_rate = 2 * hctx->ccid3hctx_x_recv; 136 __u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
138 const __u64 old_x = hctx->ccid3hctx_x; 137 const __u64 old_x = hctx->ccid3hctx_x;
139 ktime_t now = stamp? *stamp : ktime_get_real(); 138 ktime_t now = stamp ? *stamp : ktime_get_real();
140 139
141 /* 140 /*
142 * Handle IDLE periods: do not reduce below RFC3390 initial sending rate 141 * Handle IDLE periods: do not reduce below RFC3390 initial sending rate
@@ -230,27 +229,27 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
230 ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk, 229 ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
231 ccid3_tx_state_name(hctx->ccid3hctx_state)); 230 ccid3_tx_state_name(hctx->ccid3hctx_state));
232 231
233 switch (hctx->ccid3hctx_state) { 232 if (hctx->ccid3hctx_state == TFRC_SSTATE_FBACK)
234 case TFRC_SSTATE_NO_FBACK: 233 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
235 /* RFC 3448, 4.4: Halve send rate directly */ 234 else if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
235 goto out;
236
237 /*
238 * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
239 */
240 if (hctx->ccid3hctx_t_rto == 0 || /* no feedback received yet */
241 hctx->ccid3hctx_p == 0) {
242
243 /* halve send rate directly */
236 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2, 244 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
237 (((__u64)hctx->ccid3hctx_s) << 6) / 245 (((__u64)hctx->ccid3hctx_s) << 6) /
238 TFRC_T_MBI); 246 TFRC_T_MBI);
239
240 ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
241 "bytes/s\n", dccp_role(sk), sk,
242 ccid3_tx_state_name(hctx->ccid3hctx_state),
243 (unsigned)(hctx->ccid3hctx_x >> 6));
244 /* The value of R is still undefined and so we can not recompute
245 * the timeout value. Keep initial value as per [RFC 4342, 5]. */
246 t_nfb = TFRC_INITIAL_TIMEOUT;
247 ccid3_update_send_interval(hctx); 247 ccid3_update_send_interval(hctx);
248 break; 248 } else {
249 case TFRC_SSTATE_FBACK:
250 /* 249 /*
251 * Modify the cached value of X_recv [RFC 3448, 4.4] 250 * Modify the cached value of X_recv
252 * 251 *
253 * If (p == 0 || X_calc > 2 * X_recv) 252 * If (X_calc > 2 * X_recv)
254 * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 253 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
255 * Else 254 * Else
256 * X_recv = X_calc / 4; 255 * X_recv = X_calc / 4;
@@ -259,32 +258,28 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
259 */ 258 */
260 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc); 259 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
261 260
262 if (hctx->ccid3hctx_p == 0 || 261 if (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))
263 (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))) {
264
265 hctx->ccid3hctx_x_recv = 262 hctx->ccid3hctx_x_recv =
266 max(hctx->ccid3hctx_x_recv / 2, 263 max(hctx->ccid3hctx_x_recv / 2,
267 (((__u64)hctx->ccid3hctx_s) << 6) / 264 (((__u64)hctx->ccid3hctx_s) << 6) /
268 (2 * TFRC_T_MBI)); 265 (2 * TFRC_T_MBI));
269 } else { 266 else {
270 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc; 267 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
271 hctx->ccid3hctx_x_recv <<= 4; 268 hctx->ccid3hctx_x_recv <<= 4;
272 } 269 }
273 /* Now recalculate X [RFC 3448, 4.3, step (4)] */
274 ccid3_hc_tx_update_x(sk, NULL); 270 ccid3_hc_tx_update_x(sk, NULL);
275 /*
276 * Schedule no feedback timer to expire in
277 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
278 * See comments in packet_recv() regarding the value of t_RTO.
279 */
280 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
281 break;
282 case TFRC_SSTATE_NO_SENT:
283 DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
284 /* fall through */
285 case TFRC_SSTATE_TERM:
286 goto out;
287 } 271 }
272 ccid3_pr_debug("Reduced X to %llu/64 bytes/sec\n",
273 (unsigned long long)hctx->ccid3hctx_x);
274
275 /*
276 * Set new timeout for the nofeedback timer.
277 * See comments in packet_recv() regarding the value of t_RTO.
278 */
279 if (unlikely(hctx->ccid3hctx_t_rto == 0)) /* no feedback yet */
280 t_nfb = TFRC_INITIAL_TIMEOUT;
281 else
282 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
288 283
289restart_timer: 284restart_timer:
290 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 285 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,