aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/ccids/ccid3.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index a93a556ad03d..1156fef17471 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -429,40 +429,46 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
429 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ 429 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
430 hctx->ccid3hctx_p = 0; 430 hctx->ccid3hctx_p = 0;
431 else /* can not exceed 100% */ 431 else /* can not exceed 100% */
432 hctx->ccid3hctx_p = 1000000 / pinv; 432 hctx->ccid3hctx_p = scaled_div(1, pinv);
433 /* 433 /*
434 * Validate new RTT sample and update moving average 434 * Validate new RTT sample and update moving average
435 */ 435 */
436 r_sample = dccp_sample_rtt(sk, r_sample); 436 r_sample = dccp_sample_rtt(sk, r_sample);
437 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); 437 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
438 438 /*
439 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
440 */
439 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 441 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
440 /* 442 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
441 * Larger Initial Windows [RFC 4342, sec. 5]
442 */
443 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
444 hctx->ccid3hctx_t_ld = now;
445 443
446 ccid3_update_send_interval(hctx); 444 if (hctx->ccid3hctx_t_rto == 0) {
445 /*
446 * Initial feedback packet: Larger Initial Windows (4.2)
447 */
448 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
449 hctx->ccid3hctx_t_ld = now;
447 450
448 ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " 451 ccid3_update_send_interval(hctx);
449 "R_sample=%uus, X=%u\n", dccp_role(sk),
450 sk, hctx->ccid3hctx_s,
451 dccp_sk(sk)->dccps_mss_cache, r_sample,
452 (unsigned)(hctx->ccid3hctx_x >> 6));
453 452
454 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 453 goto done_computing_x;
455 } else { 454 } else if (hctx->ccid3hctx_p == 0) {
455 /*
456 * First feedback after nofeedback timer expiry (4.3)
457 */
458 goto done_computing_x;
459 }
460 }
456 461
457 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ 462 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
458 if (hctx->ccid3hctx_p > 0) 463 if (hctx->ccid3hctx_p > 0)
459 hctx->ccid3hctx_x_calc = 464 hctx->ccid3hctx_x_calc =
460 tfrc_calc_x(hctx->ccid3hctx_s, 465 tfrc_calc_x(hctx->ccid3hctx_s,
461 hctx->ccid3hctx_rtt, 466 hctx->ccid3hctx_rtt,
462 hctx->ccid3hctx_p); 467 hctx->ccid3hctx_p);
463 ccid3_hc_tx_update_x(sk, &now); 468 ccid3_hc_tx_update_x(sk, &now);
464 469
465 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, " 470done_computing_x:
471 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
466 "p=%u, X_calc=%u, X_recv=%u, X=%u\n", 472 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
467 dccp_role(sk), 473 dccp_role(sk),
468 sk, hctx->ccid3hctx_rtt, r_sample, 474 sk, hctx->ccid3hctx_rtt, r_sample,
@@ -470,7 +476,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
470 hctx->ccid3hctx_x_calc, 476 hctx->ccid3hctx_x_calc,
471 (unsigned)(hctx->ccid3hctx_x_recv >> 6), 477 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
472 (unsigned)(hctx->ccid3hctx_x >> 6)); 478 (unsigned)(hctx->ccid3hctx_x >> 6));
473 }
474 479
475 /* unschedule no feedback timer */ 480 /* unschedule no feedback timer */
476 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 481 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);