aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSamuel Jero <sj323707@ohio.edu>2011-07-24 22:49:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2011-08-01 09:52:35 -0400
commitd346d886a4c7f771c184e73833133f23a18de884 (patch)
treeb30d5ea65d37af5dd49f03712ae2f973bc71553b /net
parent31daf0393fbb17cf6efe613fb538a3ea4b5202e4 (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.c50
-rw-r--r--net/dccp/ccids/ccid2.h6
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
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).
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