diff options
| author | Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> | 2009-02-27 23:44:38 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-03-02 06:00:16 -0500 |
| commit | cabeccbd172cc305f4383f5a4808ae254745275f (patch) | |
| tree | 0504d469ae4fc1a6c1ba368b3cc99ae7f55520cb | |
| parent | 758ce5c8d11d6fc57fe5f1dbc237aa8ff6386eac (diff) | |
tcp: kill eff_sacks "cache", the sole user can calculate itself
Also fixes insignificant bug that would cause sending of stale
SACK block (would occur in some corner cases).
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/tcp.h | 1 | ||||
| -rw-r--r-- | include/net/tcp.h | 1 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 15 | ||||
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 3 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 12 |
5 files changed, 9 insertions, 23 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 0cd99e6baca5..4b86ad71e054 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
| @@ -218,7 +218,6 @@ struct tcp_options_received { | |||
| 218 | snd_wscale : 4, /* Window scaling received from sender */ | 218 | snd_wscale : 4, /* Window scaling received from sender */ |
| 219 | rcv_wscale : 4; /* Window scaling to send to receiver */ | 219 | rcv_wscale : 4; /* Window scaling to send to receiver */ |
| 220 | /* SACKs data */ | 220 | /* SACKs data */ |
| 221 | u8 eff_sacks; /* Size of SACK array to send with next packet */ | ||
| 222 | u8 num_sacks; /* Number of SACK blocks */ | 221 | u8 num_sacks; /* Number of SACK blocks */ |
| 223 | u16 user_mss; /* mss requested by user in ioctl */ | 222 | u16 user_mss; /* mss requested by user in ioctl */ |
| 224 | u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ | 223 | u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 0366a559afec..055e4946d4c8 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
| @@ -926,7 +926,6 @@ extern void tcp_done(struct sock *sk); | |||
| 926 | static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) | 926 | static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) |
| 927 | { | 927 | { |
| 928 | rx_opt->dsack = 0; | 928 | rx_opt->dsack = 0; |
| 929 | rx_opt->eff_sacks = 0; | ||
| 930 | rx_opt->num_sacks = 0; | 929 | rx_opt->num_sacks = 0; |
| 931 | } | 930 | } |
| 932 | 931 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 03f5ede87224..e4442a293eb0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -4099,7 +4099,6 @@ static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) | |||
| 4099 | tp->rx_opt.dsack = 1; | 4099 | tp->rx_opt.dsack = 1; |
| 4100 | tp->duplicate_sack[0].start_seq = seq; | 4100 | tp->duplicate_sack[0].start_seq = seq; |
| 4101 | tp->duplicate_sack[0].end_seq = end_seq; | 4101 | tp->duplicate_sack[0].end_seq = end_seq; |
| 4102 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + 1; | ||
| 4103 | } | 4102 | } |
| 4104 | } | 4103 | } |
| 4105 | 4104 | ||
| @@ -4154,8 +4153,6 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp) | |||
| 4154 | * Decrease num_sacks. | 4153 | * Decrease num_sacks. |
| 4155 | */ | 4154 | */ |
| 4156 | tp->rx_opt.num_sacks--; | 4155 | tp->rx_opt.num_sacks--; |
| 4157 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + | ||
| 4158 | tp->rx_opt.dsack; | ||
| 4159 | for (i = this_sack; i < tp->rx_opt.num_sacks; i++) | 4156 | for (i = this_sack; i < tp->rx_opt.num_sacks; i++) |
| 4160 | sp[i] = sp[i + 1]; | 4157 | sp[i] = sp[i + 1]; |
| 4161 | continue; | 4158 | continue; |
| @@ -4218,7 +4215,6 @@ new_sack: | |||
| 4218 | sp->start_seq = seq; | 4215 | sp->start_seq = seq; |
| 4219 | sp->end_seq = end_seq; | 4216 | sp->end_seq = end_seq; |
| 4220 | tp->rx_opt.num_sacks++; | 4217 | tp->rx_opt.num_sacks++; |
| 4221 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; | ||
| 4222 | } | 4218 | } |
| 4223 | 4219 | ||
| 4224 | /* RCV.NXT advances, some SACKs should be eaten. */ | 4220 | /* RCV.NXT advances, some SACKs should be eaten. */ |
| @@ -4232,7 +4228,6 @@ static void tcp_sack_remove(struct tcp_sock *tp) | |||
| 4232 | /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */ | 4228 | /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */ |
| 4233 | if (skb_queue_empty(&tp->out_of_order_queue)) { | 4229 | if (skb_queue_empty(&tp->out_of_order_queue)) { |
| 4234 | tp->rx_opt.num_sacks = 0; | 4230 | tp->rx_opt.num_sacks = 0; |
| 4235 | tp->rx_opt.eff_sacks = tp->rx_opt.dsack; | ||
| 4236 | return; | 4231 | return; |
| 4237 | } | 4232 | } |
| 4238 | 4233 | ||
| @@ -4253,11 +4248,8 @@ static void tcp_sack_remove(struct tcp_sock *tp) | |||
| 4253 | this_sack++; | 4248 | this_sack++; |
| 4254 | sp++; | 4249 | sp++; |
| 4255 | } | 4250 | } |
| 4256 | if (num_sacks != tp->rx_opt.num_sacks) { | 4251 | if (num_sacks != tp->rx_opt.num_sacks) |
| 4257 | tp->rx_opt.num_sacks = num_sacks; | 4252 | tp->rx_opt.num_sacks = num_sacks; |
| 4258 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + | ||
| 4259 | tp->rx_opt.dsack; | ||
| 4260 | } | ||
| 4261 | } | 4253 | } |
| 4262 | 4254 | ||
| 4263 | /* This one checks to see if we can put data from the | 4255 | /* This one checks to see if we can put data from the |
| @@ -4333,10 +4325,8 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
| 4333 | 4325 | ||
| 4334 | TCP_ECN_accept_cwr(tp, skb); | 4326 | TCP_ECN_accept_cwr(tp, skb); |
| 4335 | 4327 | ||
| 4336 | if (tp->rx_opt.dsack) { | 4328 | if (tp->rx_opt.dsack) |
| 4337 | tp->rx_opt.dsack = 0; | 4329 | tp->rx_opt.dsack = 0; |
| 4338 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks; | ||
| 4339 | } | ||
| 4340 | 4330 | ||
| 4341 | /* Queue data for delivery to the user. | 4331 | /* Queue data for delivery to the user. |
| 4342 | * Packets in sequence go to the receive queue. | 4332 | * Packets in sequence go to the receive queue. |
| @@ -4456,7 +4446,6 @@ drop: | |||
| 4456 | if (tcp_is_sack(tp)) { | 4446 | if (tcp_is_sack(tp)) { |
| 4457 | tp->rx_opt.num_sacks = 1; | 4447 | tp->rx_opt.num_sacks = 1; |
| 4458 | tp->rx_opt.dsack = 0; | 4448 | tp->rx_opt.dsack = 0; |
| 4459 | tp->rx_opt.eff_sacks = 1; | ||
| 4460 | tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq; | 4449 | tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq; |
| 4461 | tp->selective_acks[0].end_seq = | 4450 | tp->selective_acks[0].end_seq = |
| 4462 | TCP_SKB_CB(skb)->end_seq; | 4451 | TCP_SKB_CB(skb)->end_seq; |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f67effbb102b..bb3d8b35f19a 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -434,9 +434,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 434 | newtp->rx_opt.saw_tstamp = 0; | 434 | newtp->rx_opt.saw_tstamp = 0; |
| 435 | 435 | ||
| 436 | newtp->rx_opt.dsack = 0; | 436 | newtp->rx_opt.dsack = 0; |
| 437 | newtp->rx_opt.eff_sacks = 0; | ||
| 438 | |||
| 439 | newtp->rx_opt.num_sacks = 0; | 437 | newtp->rx_opt.num_sacks = 0; |
| 438 | |||
| 440 | newtp->urg_data = 0; | 439 | newtp->urg_data = 0; |
| 441 | 440 | ||
| 442 | if (sock_flag(newsk, SOCK_KEEPOPEN)) | 441 | if (sock_flag(newsk, SOCK_KEEPOPEN)) |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 61445b57610c..1555bb73b638 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -441,10 +441,8 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
| 441 | *ptr++ = htonl(sp[this_sack].end_seq); | 441 | *ptr++ = htonl(sp[this_sack].end_seq); |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | if (tp->rx_opt.dsack) { | 444 | if (tp->rx_opt.dsack) |
| 445 | tp->rx_opt.dsack = 0; | 445 | tp->rx_opt.dsack = 0; |
| 446 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks; | ||
| 447 | } | ||
| 448 | } | 446 | } |
| 449 | } | 447 | } |
| 450 | 448 | ||
| @@ -550,6 +548,7 @@ static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb, | |||
| 550 | struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; | 548 | struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; |
| 551 | struct tcp_sock *tp = tcp_sk(sk); | 549 | struct tcp_sock *tp = tcp_sk(sk); |
| 552 | unsigned size = 0; | 550 | unsigned size = 0; |
| 551 | unsigned int eff_sacks; | ||
| 553 | 552 | ||
| 554 | #ifdef CONFIG_TCP_MD5SIG | 553 | #ifdef CONFIG_TCP_MD5SIG |
| 555 | *md5 = tp->af_specific->md5_lookup(sk, sk); | 554 | *md5 = tp->af_specific->md5_lookup(sk, sk); |
| @@ -568,10 +567,11 @@ static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb, | |||
| 568 | size += TCPOLEN_TSTAMP_ALIGNED; | 567 | size += TCPOLEN_TSTAMP_ALIGNED; |
| 569 | } | 568 | } |
| 570 | 569 | ||
| 571 | if (unlikely(tp->rx_opt.eff_sacks)) { | 570 | eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; |
| 571 | if (unlikely(eff_sacks)) { | ||
| 572 | const unsigned remaining = MAX_TCP_OPTION_SPACE - size; | 572 | const unsigned remaining = MAX_TCP_OPTION_SPACE - size; |
| 573 | opts->num_sack_blocks = | 573 | opts->num_sack_blocks = |
| 574 | min_t(unsigned, tp->rx_opt.eff_sacks, | 574 | min_t(unsigned, eff_sacks, |
| 575 | (remaining - TCPOLEN_SACK_BASE_ALIGNED) / | 575 | (remaining - TCPOLEN_SACK_BASE_ALIGNED) / |
| 576 | TCPOLEN_SACK_PERBLOCK); | 576 | TCPOLEN_SACK_PERBLOCK); |
| 577 | size += TCPOLEN_SACK_BASE_ALIGNED + | 577 | size += TCPOLEN_SACK_BASE_ALIGNED + |
| @@ -1418,7 +1418,7 @@ static int tcp_mtu_probe(struct sock *sk) | |||
| 1418 | icsk->icsk_mtup.probe_size || | 1418 | icsk->icsk_mtup.probe_size || |
| 1419 | inet_csk(sk)->icsk_ca_state != TCP_CA_Open || | 1419 | inet_csk(sk)->icsk_ca_state != TCP_CA_Open || |
| 1420 | tp->snd_cwnd < 11 || | 1420 | tp->snd_cwnd < 11 || |
| 1421 | tp->rx_opt.eff_sacks) | 1421 | tp->rx_opt.num_sacks || tp->rx_opt.dsack) |
| 1422 | return -1; | 1422 | return -1; |
| 1423 | 1423 | ||
| 1424 | /* Very simple search strategy: just double the MSS. */ | 1424 | /* Very simple search strategy: just double the MSS. */ |
