diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 47 |
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, " | 470 | done_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); |