aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid3.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r--net/dccp/ccids/ccid3.c173
1 files changed, 84 insertions, 89 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index e31560daa0b9..a93a556ad03d 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -402,112 +402,107 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
402 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 402 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
403 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 403 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
404 return; 404 return;
405 /* ... and only in the established state */
406 if (hctx->ccid3hctx_state != TFRC_SSTATE_FBACK &&
407 hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
408 return;
405 409
406 opt_recv = &hctx->ccid3hctx_options_received; 410 opt_recv = &hctx->ccid3hctx_options_received;
411 now = ktime_get_real();
407 412
408 switch (hctx->ccid3hctx_state) { 413 /* Estimate RTT from history if ACK number is valid */
409 case TFRC_SSTATE_NO_FBACK: 414 r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist,
410 case TFRC_SSTATE_FBACK: 415 DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
411 now = ktime_get_real(); 416 if (r_sample == 0) {
412 417 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
413 /* estimate RTT from history if ACK number is valid */ 418 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type),
414 r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist, 419 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq);
415 DCCP_SKB_CB(skb)->dccpd_ack_seq, now); 420 return;
416 if (r_sample == 0) { 421 }
417 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, 422
418 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), 423 /* Update receive rate in units of 64 * bytes/second */
419 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); 424 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
420 return; 425 hctx->ccid3hctx_x_recv <<= 6;
421 }
422 426
423 /* Update receive rate in units of 64 * bytes/second */ 427 /* Update loss event rate (which is scaled by 1e6) */
424 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate; 428 pinv = opt_recv->ccid3or_loss_event_rate;
425 hctx->ccid3hctx_x_recv <<= 6; 429 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
430 hctx->ccid3hctx_p = 0;
431 else /* can not exceed 100% */
432 hctx->ccid3hctx_p = 1000000 / pinv;
433 /*
434 * Validate new RTT sample and update moving average
435 */
436 r_sample = dccp_sample_rtt(sk, r_sample);
437 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
426 438
427 /* Update loss event rate */ 439 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
428 pinv = opt_recv->ccid3or_loss_event_rate;
429 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
430 hctx->ccid3hctx_p = 0;
431 else /* can not exceed 100% */
432 hctx->ccid3hctx_p = 1000000 / pinv;
433 /* 440 /*
434 * Validate new RTT sample and update moving average 441 * Larger Initial Windows [RFC 4342, sec. 5]
435 */ 442 */
436 r_sample = dccp_sample_rtt(sk, r_sample); 443 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
437 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); 444 hctx->ccid3hctx_t_ld = now;
438 445
439 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 446 ccid3_update_send_interval(hctx);
440 /*
441 * Larger Initial Windows [RFC 4342, sec. 5]
442 */
443 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
444 hctx->ccid3hctx_t_ld = now;
445 447
446 ccid3_update_send_interval(hctx); 448 ccid3_pr_debug("%s(%p), s=%u, MSS=%u, "
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));
447 453
448 ccid3_pr_debug("%s(%p), s=%u, MSS=%u, " 454 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
449 "R_sample=%uus, X=%u\n", dccp_role(sk), 455 } else {
450 sk, hctx->ccid3hctx_s,
451 dccp_sk(sk)->dccps_mss_cache, r_sample,
452 (unsigned)(hctx->ccid3hctx_x >> 6));
453 456
454 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 457 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
455 } else { 458 if (hctx->ccid3hctx_p > 0)
459 hctx->ccid3hctx_x_calc =
460 tfrc_calc_x(hctx->ccid3hctx_s,
461 hctx->ccid3hctx_rtt,
462 hctx->ccid3hctx_p);
463 ccid3_hc_tx_update_x(sk, &now);
456 464
457 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */ 465 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
458 if (hctx->ccid3hctx_p > 0) 466 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
459 hctx->ccid3hctx_x_calc = 467 dccp_role(sk),
460 tfrc_calc_x(hctx->ccid3hctx_s, 468 sk, hctx->ccid3hctx_rtt, r_sample,
461 hctx->ccid3hctx_rtt, 469 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
462 hctx->ccid3hctx_p); 470 hctx->ccid3hctx_x_calc,
463 ccid3_hc_tx_update_x(sk, &now); 471 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
464 472 (unsigned)(hctx->ccid3hctx_x >> 6));
465 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, " 473 }
466 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
467 dccp_role(sk),
468 sk, hctx->ccid3hctx_rtt, r_sample,
469 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
470 hctx->ccid3hctx_x_calc,
471 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
472 (unsigned)(hctx->ccid3hctx_x >> 6));
473 }
474 474
475 /* unschedule no feedback timer */ 475 /* unschedule no feedback timer */
476 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 476 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
477 477
478 /* 478 /*
479 * As we have calculated new ipi, delta, t_nom it is possible 479 * As we have calculated new ipi, delta, t_nom it is possible
480 * that we now can send a packet, so wake up dccp_wait_for_ccid 480 * that we now can send a packet, so wake up dccp_wait_for_ccid
481 */ 481 */
482 sk->sk_write_space(sk); 482 sk->sk_write_space(sk);
483 483
484 /* 484 /*
485 * Update timeout interval for the nofeedback timer. 485 * Update timeout interval for the nofeedback timer.
486 * We use a configuration option to increase the lower bound. 486 * We use a configuration option to increase the lower bound.
487 * This can help avoid triggering the nofeedback timer too 487 * This can help avoid triggering the nofeedback timer too
488 * often ('spinning') on LANs with small RTTs. 488 * often ('spinning') on LANs with small RTTs.
489 */ 489 */
490 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt, 490 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
491 CONFIG_IP_DCCP_CCID3_RTO * 491 (CONFIG_IP_DCCP_CCID3_RTO *
492 (USEC_PER_SEC/1000)); 492 (USEC_PER_SEC / 1000)));
493 /* 493 /*
494 * Schedule no feedback timer to expire in 494 * Schedule no feedback timer to expire in
495 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi) 495 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
496 */ 496 */
497 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi); 497 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
498 498
499 ccid3_pr_debug("%s(%p), Scheduled no feedback timer to " 499 ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
500 "expire in %lu jiffies (%luus)\n", 500 "expire in %lu jiffies (%luus)\n",
501 dccp_role(sk), 501 dccp_role(sk),
502 sk, usecs_to_jiffies(t_nfb), t_nfb); 502 sk, usecs_to_jiffies(t_nfb), t_nfb);
503 503
504 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 504 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
505 jiffies + usecs_to_jiffies(t_nfb)); 505 jiffies + usecs_to_jiffies(t_nfb));
506 break;
507 case TFRC_SSTATE_NO_SENT: /* fall through */
508 case TFRC_SSTATE_TERM: /* ignore feedback when closing */
509 break;
510 }
511} 506}
512 507
513static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 508static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,