diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b55f60f6fcbe..6d8ab1c4efc3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct sock *sk) | |||
182 | icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); | 182 | icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); |
183 | } | 183 | } |
184 | 184 | ||
185 | void tcp_enter_quickack_mode(struct sock *sk) | 185 | static void tcp_enter_quickack_mode(struct sock *sk) |
186 | { | 186 | { |
187 | struct inet_connection_sock *icsk = inet_csk(sk); | 187 | struct inet_connection_sock *icsk = inet_csk(sk); |
188 | tcp_incr_quickack(sk); | 188 | tcp_incr_quickack(sk); |
@@ -259,8 +259,11 @@ static void tcp_fixup_sndbuf(struct sock *sk) | |||
259 | int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + | 259 | int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + |
260 | sizeof(struct sk_buff); | 260 | sizeof(struct sk_buff); |
261 | 261 | ||
262 | if (sk->sk_sndbuf < 3 * sndmem) | 262 | if (sk->sk_sndbuf < 3 * sndmem) { |
263 | sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); | 263 | sk->sk_sndbuf = 3 * sndmem; |
264 | if (sk->sk_sndbuf > sysctl_tcp_wmem[2]) | ||
265 | sk->sk_sndbuf = sysctl_tcp_wmem[2]; | ||
266 | } | ||
264 | } | 267 | } |
265 | 268 | ||
266 | /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) | 269 | /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) |
@@ -396,7 +399,7 @@ static void tcp_clamp_window(struct sock *sk) | |||
396 | if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && | 399 | if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && |
397 | !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && | 400 | !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && |
398 | !tcp_memory_pressure && | 401 | !tcp_memory_pressure && |
399 | atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { | 402 | atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { |
400 | sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), | 403 | sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), |
401 | sysctl_tcp_rmem[2]); | 404 | sysctl_tcp_rmem[2]); |
402 | } | 405 | } |
@@ -428,10 +431,10 @@ EXPORT_SYMBOL(tcp_initialize_rcv_mss); | |||
428 | * | 431 | * |
429 | * The algorithm for RTT estimation w/o timestamps is based on | 432 | * The algorithm for RTT estimation w/o timestamps is based on |
430 | * Dynamic Right-Sizing (DRS) by Wu Feng and Mike Fisk of LANL. | 433 | * Dynamic Right-Sizing (DRS) by Wu Feng and Mike Fisk of LANL. |
431 | * <http://www.lanl.gov/radiant/website/pubs/drs/lacsi2001.ps> | 434 | * <http://public.lanl.gov/radiant/pubs.html#DRS> |
432 | * | 435 | * |
433 | * More detail on this code can be found at | 436 | * More detail on this code can be found at |
434 | * <http://www.psc.edu/~jheffner/senior_thesis.ps>, | 437 | * <http://staff.psc.edu/jheffner/>, |
435 | * though this reference is out of date. A new paper | 438 | * though this reference is out of date. A new paper |
436 | * is pending. | 439 | * is pending. |
437 | */ | 440 | */ |
@@ -805,25 +808,12 @@ void tcp_update_metrics(struct sock *sk) | |||
805 | } | 808 | } |
806 | } | 809 | } |
807 | 810 | ||
808 | /* Numbers are taken from RFC3390. | ||
809 | * | ||
810 | * John Heffner states: | ||
811 | * | ||
812 | * The RFC specifies a window of no more than 4380 bytes | ||
813 | * unless 2*MSS > 4380. Reading the pseudocode in the RFC | ||
814 | * is a bit misleading because they use a clamp at 4380 bytes | ||
815 | * rather than use a multiplier in the relevant range. | ||
816 | */ | ||
817 | __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) | 811 | __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) |
818 | { | 812 | { |
819 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); | 813 | __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); |
820 | 814 | ||
821 | if (!cwnd) { | 815 | if (!cwnd) |
822 | if (tp->mss_cache > 1460) | 816 | cwnd = rfc3390_bytes_to_packets(tp->mss_cache); |
823 | cwnd = 2; | ||
824 | else | ||
825 | cwnd = (tp->mss_cache > 1095) ? 3 : 4; | ||
826 | } | ||
827 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); | 817 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); |
828 | } | 818 | } |
829 | 819 | ||
@@ -2314,7 +2304,7 @@ static inline int tcp_dupack_heuristics(struct tcp_sock *tp) | |||
2314 | 2304 | ||
2315 | static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb) | 2305 | static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb) |
2316 | { | 2306 | { |
2317 | return (tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto); | 2307 | return tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto; |
2318 | } | 2308 | } |
2319 | 2309 | ||
2320 | static inline int tcp_head_timedout(struct sock *sk) | 2310 | static inline int tcp_head_timedout(struct sock *sk) |
@@ -2508,7 +2498,7 @@ static void tcp_timeout_skbs(struct sock *sk) | |||
2508 | /* Mark head of queue up as lost. With RFC3517 SACK, the packets is | 2498 | /* Mark head of queue up as lost. With RFC3517 SACK, the packets is |
2509 | * is against sacked "cnt", otherwise it's against facked "cnt" | 2499 | * is against sacked "cnt", otherwise it's against facked "cnt" |
2510 | */ | 2500 | */ |
2511 | static void tcp_mark_head_lost(struct sock *sk, int packets) | 2501 | static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) |
2512 | { | 2502 | { |
2513 | struct tcp_sock *tp = tcp_sk(sk); | 2503 | struct tcp_sock *tp = tcp_sk(sk); |
2514 | struct sk_buff *skb; | 2504 | struct sk_buff *skb; |
@@ -2516,13 +2506,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2516 | int err; | 2506 | int err; |
2517 | unsigned int mss; | 2507 | unsigned int mss; |
2518 | 2508 | ||
2519 | if (packets == 0) | ||
2520 | return; | ||
2521 | |||
2522 | WARN_ON(packets > tp->packets_out); | 2509 | WARN_ON(packets > tp->packets_out); |
2523 | if (tp->lost_skb_hint) { | 2510 | if (tp->lost_skb_hint) { |
2524 | skb = tp->lost_skb_hint; | 2511 | skb = tp->lost_skb_hint; |
2525 | cnt = tp->lost_cnt_hint; | 2512 | cnt = tp->lost_cnt_hint; |
2513 | /* Head already handled? */ | ||
2514 | if (mark_head && skb != tcp_write_queue_head(sk)) | ||
2515 | return; | ||
2526 | } else { | 2516 | } else { |
2527 | skb = tcp_write_queue_head(sk); | 2517 | skb = tcp_write_queue_head(sk); |
2528 | cnt = 0; | 2518 | cnt = 0; |
@@ -2557,6 +2547,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2557 | } | 2547 | } |
2558 | 2548 | ||
2559 | tcp_skb_mark_lost(tp, skb); | 2549 | tcp_skb_mark_lost(tp, skb); |
2550 | |||
2551 | if (mark_head) | ||
2552 | break; | ||
2560 | } | 2553 | } |
2561 | tcp_verify_left_out(tp); | 2554 | tcp_verify_left_out(tp); |
2562 | } | 2555 | } |
@@ -2568,17 +2561,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit) | |||
2568 | struct tcp_sock *tp = tcp_sk(sk); | 2561 | struct tcp_sock *tp = tcp_sk(sk); |
2569 | 2562 | ||
2570 | if (tcp_is_reno(tp)) { | 2563 | if (tcp_is_reno(tp)) { |
2571 | tcp_mark_head_lost(sk, 1); | 2564 | tcp_mark_head_lost(sk, 1, 1); |
2572 | } else if (tcp_is_fack(tp)) { | 2565 | } else if (tcp_is_fack(tp)) { |
2573 | int lost = tp->fackets_out - tp->reordering; | 2566 | int lost = tp->fackets_out - tp->reordering; |
2574 | if (lost <= 0) | 2567 | if (lost <= 0) |
2575 | lost = 1; | 2568 | lost = 1; |
2576 | tcp_mark_head_lost(sk, lost); | 2569 | tcp_mark_head_lost(sk, lost, 0); |
2577 | } else { | 2570 | } else { |
2578 | int sacked_upto = tp->sacked_out - tp->reordering; | 2571 | int sacked_upto = tp->sacked_out - tp->reordering; |
2579 | if (sacked_upto < fast_rexmit) | 2572 | if (sacked_upto >= 0) |
2580 | sacked_upto = fast_rexmit; | 2573 | tcp_mark_head_lost(sk, sacked_upto, 0); |
2581 | tcp_mark_head_lost(sk, sacked_upto); | 2574 | else if (fast_rexmit) |
2575 | tcp_mark_head_lost(sk, 1, 1); | ||
2582 | } | 2576 | } |
2583 | 2577 | ||
2584 | tcp_timeout_skbs(sk); | 2578 | tcp_timeout_skbs(sk); |
@@ -2887,7 +2881,7 @@ static void tcp_mtup_probe_success(struct sock *sk) | |||
2887 | icsk->icsk_mtup.probe_size; | 2881 | icsk->icsk_mtup.probe_size; |
2888 | tp->snd_cwnd_cnt = 0; | 2882 | tp->snd_cwnd_cnt = 0; |
2889 | tp->snd_cwnd_stamp = tcp_time_stamp; | 2883 | tp->snd_cwnd_stamp = tcp_time_stamp; |
2890 | tp->rcv_ssthresh = tcp_current_ssthresh(sk); | 2884 | tp->snd_ssthresh = tcp_current_ssthresh(sk); |
2891 | 2885 | ||
2892 | icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size; | 2886 | icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size; |
2893 | icsk->icsk_mtup.probe_size = 0; | 2887 | icsk->icsk_mtup.probe_size = 0; |
@@ -2984,7 +2978,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) | |||
2984 | before(tp->snd_una, tp->high_seq) && | 2978 | before(tp->snd_una, tp->high_seq) && |
2985 | icsk->icsk_ca_state != TCP_CA_Open && | 2979 | icsk->icsk_ca_state != TCP_CA_Open && |
2986 | tp->fackets_out > tp->reordering) { | 2980 | tp->fackets_out > tp->reordering) { |
2987 | tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); | 2981 | tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0); |
2988 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); | 2982 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); |
2989 | } | 2983 | } |
2990 | 2984 | ||
@@ -3412,8 +3406,8 @@ static void tcp_ack_probe(struct sock *sk) | |||
3412 | 3406 | ||
3413 | static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag) | 3407 | static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag) |
3414 | { | 3408 | { |
3415 | return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || | 3409 | return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || |
3416 | inet_csk(sk)->icsk_ca_state != TCP_CA_Open); | 3410 | inet_csk(sk)->icsk_ca_state != TCP_CA_Open; |
3417 | } | 3411 | } |
3418 | 3412 | ||
3419 | static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag) | 3413 | static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag) |
@@ -3430,9 +3424,9 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp, | |||
3430 | const u32 ack, const u32 ack_seq, | 3424 | const u32 ack, const u32 ack_seq, |
3431 | const u32 nwin) | 3425 | const u32 nwin) |
3432 | { | 3426 | { |
3433 | return (after(ack, tp->snd_una) || | 3427 | return after(ack, tp->snd_una) || |
3434 | after(ack_seq, tp->snd_wl1) || | 3428 | after(ack_seq, tp->snd_wl1) || |
3435 | (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); | 3429 | (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd); |
3436 | } | 3430 | } |
3437 | 3431 | ||
3438 | /* Update our send window. | 3432 | /* Update our send window. |
@@ -4870,7 +4864,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk) | |||
4870 | return 0; | 4864 | return 0; |
4871 | 4865 | ||
4872 | /* If we are under soft global TCP memory pressure, do not expand. */ | 4866 | /* If we are under soft global TCP memory pressure, do not expand. */ |
4873 | if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) | 4867 | if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) |
4874 | return 0; | 4868 | return 0; |
4875 | 4869 | ||
4876 | /* If we filled the congestion window, do not expand. */ | 4870 | /* If we filled the congestion window, do not expand. */ |