diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-06 20:22:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-06 20:22:09 -0500 |
commit | 9753dfe19a85e7e45a34a56f4cb2048bb4f50e27 (patch) | |
tree | c017a1b4a70b8447c71b01d8b320e071546b5c9d /net/ipv4/tcp_input.c | |
parent | edf7c8148ec40c0fd27c0ef3f688defcc65e3913 (diff) | |
parent | 9f42f126154786e6e76df513004800c8c633f020 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1958 commits)
net: pack skb_shared_info more efficiently
net_sched: red: split red_parms into parms and vars
net_sched: sfq: extend limits
cnic: Improve error recovery on bnx2x devices
cnic: Re-init dev->stats_addr after chip reset
net_sched: Bug in netem reordering
bna: fix sparse warnings/errors
bna: make ethtool_ops and strings const
xgmac: cleanups
net: make ethtool_ops const
vmxnet3" make ethtool ops const
xen-netback: make ops structs const
virtio_net: Pass gfp flags when allocating rx buffers.
ixgbe: FCoE: Add support for ndo_get_fcoe_hbainfo() call
netdev: FCoE: Add new ndo_get_fcoe_hbainfo() call
igb: reset PHY after recovering from PHY power down
igb: add basic runtime PM support
igb: Add support for byte queue limits.
e1000: cleanup CE4100 MDIO registers access
e1000: unmap ce4100_gbe_mdio_base_virt in e1000_remove
...
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 52b5c2d0ecd0..2877c3e09587 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -322,7 +322,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) | |||
322 | /* Check #1 */ | 322 | /* Check #1 */ |
323 | if (tp->rcv_ssthresh < tp->window_clamp && | 323 | if (tp->rcv_ssthresh < tp->window_clamp && |
324 | (int)tp->rcv_ssthresh < tcp_space(sk) && | 324 | (int)tp->rcv_ssthresh < tcp_space(sk) && |
325 | !tcp_memory_pressure) { | 325 | !sk_under_memory_pressure(sk)) { |
326 | int incr; | 326 | int incr; |
327 | 327 | ||
328 | /* Check #2. Increase window, if skb with such overhead | 328 | /* Check #2. Increase window, if skb with such overhead |
@@ -411,8 +411,8 @@ static void tcp_clamp_window(struct sock *sk) | |||
411 | 411 | ||
412 | if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && | 412 | if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && |
413 | !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && | 413 | !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && |
414 | !tcp_memory_pressure && | 414 | !sk_under_memory_pressure(sk) && |
415 | atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { | 415 | sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)) { |
416 | sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), | 416 | sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), |
417 | sysctl_tcp_rmem[2]); | 417 | sysctl_tcp_rmem[2]); |
418 | } | 418 | } |
@@ -865,13 +865,13 @@ static void tcp_disable_fack(struct tcp_sock *tp) | |||
865 | /* RFC3517 uses different metric in lost marker => reset on change */ | 865 | /* RFC3517 uses different metric in lost marker => reset on change */ |
866 | if (tcp_is_fack(tp)) | 866 | if (tcp_is_fack(tp)) |
867 | tp->lost_skb_hint = NULL; | 867 | tp->lost_skb_hint = NULL; |
868 | tp->rx_opt.sack_ok &= ~2; | 868 | tp->rx_opt.sack_ok &= ~TCP_FACK_ENABLED; |
869 | } | 869 | } |
870 | 870 | ||
871 | /* Take a notice that peer is sending D-SACKs */ | 871 | /* Take a notice that peer is sending D-SACKs */ |
872 | static void tcp_dsack_seen(struct tcp_sock *tp) | 872 | static void tcp_dsack_seen(struct tcp_sock *tp) |
873 | { | 873 | { |
874 | tp->rx_opt.sack_ok |= 4; | 874 | tp->rx_opt.sack_ok |= TCP_DSACK_SEEN; |
875 | } | 875 | } |
876 | 876 | ||
877 | /* Initialize metrics on socket. */ | 877 | /* Initialize metrics on socket. */ |
@@ -2663,7 +2663,7 @@ static void DBGUNDO(struct sock *sk, const char *msg) | |||
2663 | tp->snd_ssthresh, tp->prior_ssthresh, | 2663 | tp->snd_ssthresh, tp->prior_ssthresh, |
2664 | tp->packets_out); | 2664 | tp->packets_out); |
2665 | } | 2665 | } |
2666 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 2666 | #if IS_ENABLED(CONFIG_IPV6) |
2667 | else if (sk->sk_family == AF_INET6) { | 2667 | else if (sk->sk_family == AF_INET6) { |
2668 | struct ipv6_pinfo *np = inet6_sk(sk); | 2668 | struct ipv6_pinfo *np = inet6_sk(sk); |
2669 | printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", | 2669 | printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", |
@@ -2858,7 +2858,7 @@ static void tcp_try_keep_open(struct sock *sk) | |||
2858 | struct tcp_sock *tp = tcp_sk(sk); | 2858 | struct tcp_sock *tp = tcp_sk(sk); |
2859 | int state = TCP_CA_Open; | 2859 | int state = TCP_CA_Open; |
2860 | 2860 | ||
2861 | if (tcp_left_out(tp) || tcp_any_retrans_done(sk) || tp->undo_marker) | 2861 | if (tcp_left_out(tp) || tcp_any_retrans_done(sk)) |
2862 | state = TCP_CA_Disorder; | 2862 | state = TCP_CA_Disorder; |
2863 | 2863 | ||
2864 | if (inet_csk(sk)->icsk_ca_state != state) { | 2864 | if (inet_csk(sk)->icsk_ca_state != state) { |
@@ -2881,7 +2881,8 @@ static void tcp_try_to_open(struct sock *sk, int flag) | |||
2881 | 2881 | ||
2882 | if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { | 2882 | if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { |
2883 | tcp_try_keep_open(sk); | 2883 | tcp_try_keep_open(sk); |
2884 | tcp_moderate_cwnd(tp); | 2884 | if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open) |
2885 | tcp_moderate_cwnd(tp); | ||
2885 | } else { | 2886 | } else { |
2886 | tcp_cwnd_down(sk, flag); | 2887 | tcp_cwnd_down(sk, flag); |
2887 | } | 2888 | } |
@@ -3009,11 +3010,11 @@ static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked, | |||
3009 | * tcp_xmit_retransmit_queue(). | 3010 | * tcp_xmit_retransmit_queue(). |
3010 | */ | 3011 | */ |
3011 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | 3012 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, |
3012 | int newly_acked_sacked, int flag) | 3013 | int newly_acked_sacked, bool is_dupack, |
3014 | int flag) | ||
3013 | { | 3015 | { |
3014 | struct inet_connection_sock *icsk = inet_csk(sk); | 3016 | struct inet_connection_sock *icsk = inet_csk(sk); |
3015 | struct tcp_sock *tp = tcp_sk(sk); | 3017 | struct tcp_sock *tp = tcp_sk(sk); |
3016 | int is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); | ||
3017 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && | 3018 | int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && |
3018 | (tcp_fackets_out(tp) > tp->reordering)); | 3019 | (tcp_fackets_out(tp) > tp->reordering)); |
3019 | int fast_rexmit = 0, mib_idx; | 3020 | int fast_rexmit = 0, mib_idx; |
@@ -3066,17 +3067,6 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | |||
3066 | } | 3067 | } |
3067 | break; | 3068 | break; |
3068 | 3069 | ||
3069 | case TCP_CA_Disorder: | ||
3070 | tcp_try_undo_dsack(sk); | ||
3071 | if (!tp->undo_marker || | ||
3072 | /* For SACK case do not Open to allow to undo | ||
3073 | * catching for all duplicate ACKs. */ | ||
3074 | tcp_is_reno(tp) || tp->snd_una != tp->high_seq) { | ||
3075 | tp->undo_marker = 0; | ||
3076 | tcp_set_ca_state(sk, TCP_CA_Open); | ||
3077 | } | ||
3078 | break; | ||
3079 | |||
3080 | case TCP_CA_Recovery: | 3070 | case TCP_CA_Recovery: |
3081 | if (tcp_is_reno(tp)) | 3071 | if (tcp_is_reno(tp)) |
3082 | tcp_reset_reno_sack(tp); | 3072 | tcp_reset_reno_sack(tp); |
@@ -3117,7 +3107,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | |||
3117 | tcp_add_reno_sack(sk); | 3107 | tcp_add_reno_sack(sk); |
3118 | } | 3108 | } |
3119 | 3109 | ||
3120 | if (icsk->icsk_ca_state == TCP_CA_Disorder) | 3110 | if (icsk->icsk_ca_state <= TCP_CA_Disorder) |
3121 | tcp_try_undo_dsack(sk); | 3111 | tcp_try_undo_dsack(sk); |
3122 | 3112 | ||
3123 | if (!tcp_time_to_recover(sk)) { | 3113 | if (!tcp_time_to_recover(sk)) { |
@@ -3681,10 +3671,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3681 | u32 prior_snd_una = tp->snd_una; | 3671 | u32 prior_snd_una = tp->snd_una; |
3682 | u32 ack_seq = TCP_SKB_CB(skb)->seq; | 3672 | u32 ack_seq = TCP_SKB_CB(skb)->seq; |
3683 | u32 ack = TCP_SKB_CB(skb)->ack_seq; | 3673 | u32 ack = TCP_SKB_CB(skb)->ack_seq; |
3674 | bool is_dupack = false; | ||
3684 | u32 prior_in_flight; | 3675 | u32 prior_in_flight; |
3685 | u32 prior_fackets; | 3676 | u32 prior_fackets; |
3686 | int prior_packets; | 3677 | int prior_packets; |
3687 | int prior_sacked = tp->sacked_out; | 3678 | int prior_sacked = tp->sacked_out; |
3679 | int pkts_acked = 0; | ||
3688 | int newly_acked_sacked = 0; | 3680 | int newly_acked_sacked = 0; |
3689 | int frto_cwnd = 0; | 3681 | int frto_cwnd = 0; |
3690 | 3682 | ||
@@ -3757,6 +3749,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3757 | /* See if we can take anything off of the retransmit queue. */ | 3749 | /* See if we can take anything off of the retransmit queue. */ |
3758 | flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); | 3750 | flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); |
3759 | 3751 | ||
3752 | pkts_acked = prior_packets - tp->packets_out; | ||
3760 | newly_acked_sacked = (prior_packets - prior_sacked) - | 3753 | newly_acked_sacked = (prior_packets - prior_sacked) - |
3761 | (tp->packets_out - tp->sacked_out); | 3754 | (tp->packets_out - tp->sacked_out); |
3762 | 3755 | ||
@@ -3771,8 +3764,9 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3771 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd && | 3764 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd && |
3772 | tcp_may_raise_cwnd(sk, flag)) | 3765 | tcp_may_raise_cwnd(sk, flag)) |
3773 | tcp_cong_avoid(sk, ack, prior_in_flight); | 3766 | tcp_cong_avoid(sk, ack, prior_in_flight); |
3774 | tcp_fastretrans_alert(sk, prior_packets - tp->packets_out, | 3767 | is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); |
3775 | newly_acked_sacked, flag); | 3768 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, |
3769 | is_dupack, flag); | ||
3776 | } else { | 3770 | } else { |
3777 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) | 3771 | if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) |
3778 | tcp_cong_avoid(sk, ack, prior_in_flight); | 3772 | tcp_cong_avoid(sk, ack, prior_in_flight); |
@@ -3784,6 +3778,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3784 | return 1; | 3778 | return 1; |
3785 | 3779 | ||
3786 | no_queue: | 3780 | no_queue: |
3781 | /* If data was DSACKed, see if we can undo a cwnd reduction. */ | ||
3782 | if (flag & FLAG_DSACKING_ACK) | ||
3783 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, | ||
3784 | is_dupack, flag); | ||
3787 | /* If this ack opens up a zero window, clear backoff. It was | 3785 | /* If this ack opens up a zero window, clear backoff. It was |
3788 | * being used to time the probes, and is probably far higher than | 3786 | * being used to time the probes, and is probably far higher than |
3789 | * it needs to be for normal retransmission. | 3787 | * it needs to be for normal retransmission. |
@@ -3797,10 +3795,14 @@ invalid_ack: | |||
3797 | return -1; | 3795 | return -1; |
3798 | 3796 | ||
3799 | old_ack: | 3797 | old_ack: |
3798 | /* If data was SACKed, tag it and see if we should send more data. | ||
3799 | * If data was DSACKed, see if we can undo a cwnd reduction. | ||
3800 | */ | ||
3800 | if (TCP_SKB_CB(skb)->sacked) { | 3801 | if (TCP_SKB_CB(skb)->sacked) { |
3801 | tcp_sacktag_write_queue(sk, skb, prior_snd_una); | 3802 | flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); |
3802 | if (icsk->icsk_ca_state == TCP_CA_Open) | 3803 | newly_acked_sacked = tp->sacked_out - prior_sacked; |
3803 | tcp_try_keep_open(sk); | 3804 | tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, |
3805 | is_dupack, flag); | ||
3804 | } | 3806 | } |
3805 | 3807 | ||
3806 | SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); | 3808 | SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); |
@@ -3876,7 +3878,7 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o | |||
3876 | case TCPOPT_SACK_PERM: | 3878 | case TCPOPT_SACK_PERM: |
3877 | if (opsize == TCPOLEN_SACK_PERM && th->syn && | 3879 | if (opsize == TCPOLEN_SACK_PERM && th->syn && |
3878 | !estab && sysctl_tcp_sack) { | 3880 | !estab && sysctl_tcp_sack) { |
3879 | opt_rx->sack_ok = 1; | 3881 | opt_rx->sack_ok = TCP_SACK_SEEN; |
3880 | tcp_sack_reset(opt_rx); | 3882 | tcp_sack_reset(opt_rx); |
3881 | } | 3883 | } |
3882 | break; | 3884 | break; |
@@ -4864,7 +4866,7 @@ static int tcp_prune_queue(struct sock *sk) | |||
4864 | 4866 | ||
4865 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) | 4867 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) |
4866 | tcp_clamp_window(sk); | 4868 | tcp_clamp_window(sk); |
4867 | else if (tcp_memory_pressure) | 4869 | else if (sk_under_memory_pressure(sk)) |
4868 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); | 4870 | tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); |
4869 | 4871 | ||
4870 | tcp_collapse_ofo_queue(sk); | 4872 | tcp_collapse_ofo_queue(sk); |
@@ -4930,11 +4932,11 @@ static int tcp_should_expand_sndbuf(const struct sock *sk) | |||
4930 | return 0; | 4932 | return 0; |
4931 | 4933 | ||
4932 | /* If we are under global TCP memory pressure, do not expand. */ | 4934 | /* If we are under global TCP memory pressure, do not expand. */ |
4933 | if (tcp_memory_pressure) | 4935 | if (sk_under_memory_pressure(sk)) |
4934 | return 0; | 4936 | return 0; |
4935 | 4937 | ||
4936 | /* If we are under soft global TCP memory pressure, do not expand. */ | 4938 | /* If we are under soft global TCP memory pressure, do not expand. */ |
4937 | if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) | 4939 | if (sk_memory_allocated(sk) >= sk_prot_mem_limits(sk, 0)) |
4938 | return 0; | 4940 | return 0; |
4939 | 4941 | ||
4940 | /* If we filled the congestion window, do not expand. */ | 4942 | /* If we filled the congestion window, do not expand. */ |
@@ -5809,6 +5811,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5809 | goto discard; | 5811 | goto discard; |
5810 | 5812 | ||
5811 | if (th->syn) { | 5813 | if (th->syn) { |
5814 | if (th->fin) | ||
5815 | goto discard; | ||
5812 | if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) | 5816 | if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) |
5813 | return 1; | 5817 | return 1; |
5814 | 5818 | ||