aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids/ccid2.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ccids/ccid2.c')
-rw-r--r--net/dccp/ccids/ccid2.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index b51cc92376da..9dbc4d88af16 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -85,7 +85,6 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
85 85
86static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) 86static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
87{ 87{
88 struct dccp_sock *dp = dccp_sk(sk);
89 u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->tx_cwnd, 2); 88 u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->tx_cwnd, 2);
90 89
91 /* 90 /*
@@ -98,14 +97,15 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
98 DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio); 97 DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
99 val = max_ratio; 98 val = max_ratio;
100 } 99 }
101 if (val > DCCPF_ACK_RATIO_MAX) 100 dccp_feat_signal_nn_change(sk, DCCPF_ACK_RATIO,
102 val = DCCPF_ACK_RATIO_MAX; 101 min_t(u32, val, DCCPF_ACK_RATIO_MAX));
103 102}
104 if (val == dp->dccps_l_ack_ratio)
105 return;
106 103
107 ccid2_pr_debug("changing local ack ratio to %u\n", val); 104static void ccid2_change_l_seq_window(struct sock *sk, u64 val)
108 dp->dccps_l_ack_ratio = val; 105{
106 dccp_feat_signal_nn_change(sk, DCCPF_SEQUENCE_WINDOW,
107 clamp_val(val, DCCPF_SEQ_WMIN,
108 DCCPF_SEQ_WMAX));
109} 109}
110 110
111static void ccid2_hc_tx_rto_expire(unsigned long data) 111static void ccid2_hc_tx_rto_expire(unsigned long data)
@@ -405,17 +405,37 @@ static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp,
405 unsigned int *maxincr) 405 unsigned int *maxincr)
406{ 406{
407 struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); 407 struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
408 408 struct dccp_sock *dp = dccp_sk(sk);
409 if (hc->tx_cwnd < hc->tx_ssthresh) { 409 int r_seq_used = hc->tx_cwnd / dp->dccps_l_ack_ratio;
410 if (*maxincr > 0 && ++hc->tx_packets_acked == 2) { 410
411 if (hc->tx_cwnd < dp->dccps_l_seq_win &&
412 r_seq_used < dp->dccps_r_seq_win) {
413 if (hc->tx_cwnd < hc->tx_ssthresh) {
414 if (*maxincr > 0 && ++hc->tx_packets_acked == 2) {
415 hc->tx_cwnd += 1;
416 *maxincr -= 1;
417 hc->tx_packets_acked = 0;
418 }
419 } else if (++hc->tx_packets_acked >= hc->tx_cwnd) {
411 hc->tx_cwnd += 1; 420 hc->tx_cwnd += 1;
412 *maxincr -= 1;
413 hc->tx_packets_acked = 0; 421 hc->tx_packets_acked = 0;
414 } 422 }
415 } else if (++hc->tx_packets_acked >= hc->tx_cwnd) {
416 hc->tx_cwnd += 1;
417 hc->tx_packets_acked = 0;
418 } 423 }
424
425 /*
426 * Adjust the local sequence window and the ack ratio to allow about
427 * 5 times the number of packets in the network (RFC 4340 7.5.2)
428 */
429 if (r_seq_used * CCID2_WIN_CHANGE_FACTOR >= dp->dccps_r_seq_win)
430 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio * 2);
431 else if (r_seq_used * CCID2_WIN_CHANGE_FACTOR < dp->dccps_r_seq_win/2)
432 ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio / 2 ? : 1U);
433
434 if (hc->tx_cwnd * CCID2_WIN_CHANGE_FACTOR >= dp->dccps_l_seq_win)
435 ccid2_change_l_seq_window(sk, dp->dccps_l_seq_win * 2);
436 else if (hc->tx_cwnd * CCID2_WIN_CHANGE_FACTOR < dp->dccps_l_seq_win/2)
437 ccid2_change_l_seq_window(sk, dp->dccps_l_seq_win / 2);
438
419 /* 439 /*
420 * FIXME: RTT is sampled several times per acknowledgment (for each 440 * FIXME: RTT is sampled several times per acknowledgment (for each
421 * entry in the Ack Vector), instead of once per Ack (as in TCP SACK). 441 * entry in the Ack Vector), instead of once per Ack (as in TCP SACK).