diff options
author | Samuel Jero <sj323707@ohio.edu> | 2011-07-24 22:49:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2011-08-01 09:52:35 -0400 |
commit | d346d886a4c7f771c184e73833133f23a18de884 (patch) | |
tree | b30d5ea65d37af5dd49f03712ae2f973bc71553b /net | |
parent | 31daf0393fbb17cf6efe613fb538a3ea4b5202e4 (diff) |
dccp ccid-2: prevent cwnd > Sequence Window
Add a check to prevent CCID-2 from increasing the cwnd greater than the
Sequence Window.
When the congestion window becomes bigger than the Sequence Window, CCID-2
will attempt to keep more data in the network than the DCCP Sequence Window
code considers possible. This results in the Sequence Window code issuing
a Sync, thereby inducing needless overhead. Further, if this occurs at the
sender, CCID-2 will never detect the problem because the Acks it receives
will indicate no losses. I have seen this cause a drop of 1/3rd in throughput
for a connection.
Also add code to adjust the Sequence Window to be about 5 times the number of
packets in the network (RFC 4340, 7.5.2) and to adjust the Ack Ratio so that
the remote Sequence Window will hold about 5 times the number of packets in
the network. This allows the congestion window to increase correctly without
being limited by the Sequence Window.
Signed-off-by: Samuel Jero <sj323707@ohio.edu>
Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net')
-rw-r--r-- | net/dccp/ccids/ccid2.c | 50 | ||||
-rw-r--r-- | net/dccp/ccids/ccid2.h | 6 |
2 files changed, 41 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 | ||
86 | static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) | 86 | static 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); | 104 | static 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 | ||
111 | static void ccid2_hc_tx_rto_expire(unsigned long data) | 111 | static 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). |
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index f585d330e1e5..18c97543e522 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h | |||
@@ -43,6 +43,12 @@ struct ccid2_seq { | |||
43 | #define CCID2_SEQBUF_LEN 1024 | 43 | #define CCID2_SEQBUF_LEN 1024 |
44 | #define CCID2_SEQBUF_MAX 128 | 44 | #define CCID2_SEQBUF_MAX 128 |
45 | 45 | ||
46 | /* | ||
47 | * Multiple of congestion window to keep the sequence window at | ||
48 | * (RFC 4340 7.5.2) | ||
49 | */ | ||
50 | #define CCID2_WIN_CHANGE_FACTOR 5 | ||
51 | |||
46 | /** | 52 | /** |
47 | * struct ccid2_hc_tx_sock - CCID2 TX half connection | 53 | * struct ccid2_hc_tx_sock - CCID2 TX half connection |
48 | * @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5 | 54 | * @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5 |