aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyousei Takano <takano-ryousei@aist.go.jp>2007-10-26 07:27:59 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-26 07:27:59 -0400
commit94d3b1e586f6d4c7150501bde284c544ce99073c (patch)
tree6c05886d3ee3ddc30f6b3fce3b6acb27eeab4300
parent43cc7380eced27ee9cafdf89fa32333dc3884e8b (diff)
[TCP]: fix D-SACK cwnd handling
In the current net-2.6 kernel, handling FLAG_DSACKING_ACK is broken. The flag is cleared to 1 just after FLAG_DSACKING_ACK is set. if (found_dup_sack) flag |= FLAG_DSACKING_ACK; : flag = 1; To fix it, this patch introduces a part of the tcp_sacktag_state patch: http://marc.info/?l=linux-netdev&m=119210560431519&w=2 Signed-off-by: Ryousei Takano <takano-ryousei@aist.go.jp> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_input.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 457697a043d9..69d8c38ccd39 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1248,6 +1248,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1248 int cached_fack_count; 1248 int cached_fack_count;
1249 int i; 1249 int i;
1250 int first_sack_index; 1250 int first_sack_index;
1251 int force_one_sack;
1251 1252
1252 if (!tp->sacked_out) { 1253 if (!tp->sacked_out) {
1253 if (WARN_ON(tp->fackets_out)) 1254 if (WARN_ON(tp->fackets_out))
@@ -1272,18 +1273,18 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1272 * if the only SACK change is the increase of the end_seq of 1273 * if the only SACK change is the increase of the end_seq of
1273 * the first block then only apply that SACK block 1274 * the first block then only apply that SACK block
1274 * and use retrans queue hinting otherwise slowpath */ 1275 * and use retrans queue hinting otherwise slowpath */
1275 flag = 1; 1276 force_one_sack = 1;
1276 for (i = 0; i < num_sacks; i++) { 1277 for (i = 0; i < num_sacks; i++) {
1277 __be32 start_seq = sp[i].start_seq; 1278 __be32 start_seq = sp[i].start_seq;
1278 __be32 end_seq = sp[i].end_seq; 1279 __be32 end_seq = sp[i].end_seq;
1279 1280
1280 if (i == 0) { 1281 if (i == 0) {
1281 if (tp->recv_sack_cache[i].start_seq != start_seq) 1282 if (tp->recv_sack_cache[i].start_seq != start_seq)
1282 flag = 0; 1283 force_one_sack = 0;
1283 } else { 1284 } else {
1284 if ((tp->recv_sack_cache[i].start_seq != start_seq) || 1285 if ((tp->recv_sack_cache[i].start_seq != start_seq) ||
1285 (tp->recv_sack_cache[i].end_seq != end_seq)) 1286 (tp->recv_sack_cache[i].end_seq != end_seq))
1286 flag = 0; 1287 force_one_sack = 0;
1287 } 1288 }
1288 tp->recv_sack_cache[i].start_seq = start_seq; 1289 tp->recv_sack_cache[i].start_seq = start_seq;
1289 tp->recv_sack_cache[i].end_seq = end_seq; 1290 tp->recv_sack_cache[i].end_seq = end_seq;
@@ -1295,7 +1296,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1295 } 1296 }
1296 1297
1297 first_sack_index = 0; 1298 first_sack_index = 0;
1298 if (flag) 1299 if (force_one_sack)
1299 num_sacks = 1; 1300 num_sacks = 1;
1300 else { 1301 else {
1301 int j; 1302 int j;
@@ -1321,9 +1322,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1321 } 1322 }
1322 } 1323 }
1323 1324
1324 /* clear flag as used for different purpose in following code */
1325 flag = 0;
1326
1327 /* Use SACK fastpath hint if valid */ 1325 /* Use SACK fastpath hint if valid */
1328 cached_skb = tp->fastpath_skb_hint; 1326 cached_skb = tp->fastpath_skb_hint;
1329 cached_fack_count = tp->fastpath_cnt_hint; 1327 cached_fack_count = tp->fastpath_cnt_hint;