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/dccp | |
| 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/dccp')
| -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 |
