diff options
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b2f6c74861af..6e5617b9f9db 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -283,6 +283,8 @@ | |||
| 283 | 283 | ||
| 284 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; | 284 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; |
| 285 | 285 | ||
| 286 | int sysctl_tcp_min_tso_segs __read_mostly = 2; | ||
| 287 | |||
| 286 | struct percpu_counter tcp_orphan_count; | 288 | struct percpu_counter tcp_orphan_count; |
| 287 | EXPORT_SYMBOL_GPL(tcp_orphan_count); | 289 | EXPORT_SYMBOL_GPL(tcp_orphan_count); |
| 288 | 290 | ||
| @@ -410,10 +412,6 @@ void tcp_init_sock(struct sock *sk) | |||
| 410 | 412 | ||
| 411 | icsk->icsk_sync_mss = tcp_sync_mss; | 413 | icsk->icsk_sync_mss = tcp_sync_mss; |
| 412 | 414 | ||
| 413 | /* Presumed zeroed, in order of appearance: | ||
| 414 | * cookie_in_always, cookie_out_never, | ||
| 415 | * s_data_constant, s_data_in, s_data_out | ||
| 416 | */ | ||
| 417 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; | 415 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; |
| 418 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; | 416 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |
| 419 | 417 | ||
| @@ -499,7 +497,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 499 | mask |= POLLIN | POLLRDNORM; | 497 | mask |= POLLIN | POLLRDNORM; |
| 500 | 498 | ||
| 501 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { | 499 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { |
| 502 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) { | 500 | if (sk_stream_is_writeable(sk)) { |
| 503 | mask |= POLLOUT | POLLWRNORM; | 501 | mask |= POLLOUT | POLLWRNORM; |
| 504 | } else { /* send SIGIO later */ | 502 | } else { /* send SIGIO later */ |
| 505 | set_bit(SOCK_ASYNC_NOSPACE, | 503 | set_bit(SOCK_ASYNC_NOSPACE, |
| @@ -510,7 +508,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 510 | * wspace test but before the flags are set, | 508 | * wspace test but before the flags are set, |
| 511 | * IO signal will be lost. | 509 | * IO signal will be lost. |
| 512 | */ | 510 | */ |
| 513 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 511 | if (sk_stream_is_writeable(sk)) |
| 514 | mask |= POLLOUT | POLLWRNORM; | 512 | mask |= POLLOUT | POLLWRNORM; |
| 515 | } | 513 | } |
| 516 | } else | 514 | } else |
| @@ -789,12 +787,28 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, | |||
| 789 | xmit_size_goal = mss_now; | 787 | xmit_size_goal = mss_now; |
| 790 | 788 | ||
| 791 | if (large_allowed && sk_can_gso(sk)) { | 789 | if (large_allowed && sk_can_gso(sk)) { |
| 792 | xmit_size_goal = ((sk->sk_gso_max_size - 1) - | 790 | u32 gso_size, hlen; |
| 793 | inet_csk(sk)->icsk_af_ops->net_header_len - | 791 | |
| 794 | inet_csk(sk)->icsk_ext_hdr_len - | 792 | /* Maybe we should/could use sk->sk_prot->max_header here ? */ |
| 795 | tp->tcp_header_len); | 793 | hlen = inet_csk(sk)->icsk_af_ops->net_header_len + |
| 794 | inet_csk(sk)->icsk_ext_hdr_len + | ||
| 795 | tp->tcp_header_len; | ||
| 796 | |||
| 797 | /* Goal is to send at least one packet per ms, | ||
| 798 | * not one big TSO packet every 100 ms. | ||
| 799 | * This preserves ACK clocking and is consistent | ||
| 800 | * with tcp_tso_should_defer() heuristic. | ||
| 801 | */ | ||
| 802 | gso_size = sk->sk_pacing_rate / (2 * MSEC_PER_SEC); | ||
| 803 | gso_size = max_t(u32, gso_size, | ||
| 804 | sysctl_tcp_min_tso_segs * mss_now); | ||
| 805 | |||
| 806 | xmit_size_goal = min_t(u32, gso_size, | ||
| 807 | sk->sk_gso_max_size - 1 - hlen); | ||
| 796 | 808 | ||
| 797 | /* TSQ : try to have two TSO segments in flight */ | 809 | /* TSQ : try to have at least two segments in flight |
| 810 | * (one in NIC TX ring, another in Qdisc) | ||
| 811 | */ | ||
| 798 | xmit_size_goal = min_t(u32, xmit_size_goal, | 812 | xmit_size_goal = min_t(u32, xmit_size_goal, |
| 799 | sysctl_tcp_limit_output_bytes >> 1); | 813 | sysctl_tcp_limit_output_bytes >> 1); |
| 800 | 814 | ||
| @@ -2454,10 +2468,11 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2454 | case TCP_THIN_DUPACK: | 2468 | case TCP_THIN_DUPACK: |
| 2455 | if (val < 0 || val > 1) | 2469 | if (val < 0 || val > 1) |
| 2456 | err = -EINVAL; | 2470 | err = -EINVAL; |
| 2457 | else | 2471 | else { |
| 2458 | tp->thin_dupack = val; | 2472 | tp->thin_dupack = val; |
| 2459 | if (tp->thin_dupack) | 2473 | if (tp->thin_dupack) |
| 2460 | tcp_disable_early_retrans(tp); | 2474 | tcp_disable_early_retrans(tp); |
| 2475 | } | ||
| 2461 | break; | 2476 | break; |
| 2462 | 2477 | ||
| 2463 | case TCP_REPAIR: | 2478 | case TCP_REPAIR: |
| @@ -2638,6 +2653,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2638 | else | 2653 | else |
| 2639 | tp->tsoffset = val - tcp_time_stamp; | 2654 | tp->tsoffset = val - tcp_time_stamp; |
| 2640 | break; | 2655 | break; |
| 2656 | case TCP_NOTSENT_LOWAT: | ||
| 2657 | tp->notsent_lowat = val; | ||
| 2658 | sk->sk_write_space(sk); | ||
| 2659 | break; | ||
| 2641 | default: | 2660 | default: |
| 2642 | err = -ENOPROTOOPT; | 2661 | err = -ENOPROTOOPT; |
| 2643 | break; | 2662 | break; |
| @@ -2854,6 +2873,9 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
| 2854 | case TCP_TIMESTAMP: | 2873 | case TCP_TIMESTAMP: |
| 2855 | val = tcp_time_stamp + tp->tsoffset; | 2874 | val = tcp_time_stamp + tp->tsoffset; |
| 2856 | break; | 2875 | break; |
| 2876 | case TCP_NOTSENT_LOWAT: | ||
| 2877 | val = tp->notsent_lowat; | ||
| 2878 | break; | ||
| 2857 | default: | 2879 | default: |
| 2858 | return -ENOPROTOOPT; | 2880 | return -ENOPROTOOPT; |
| 2859 | } | 2881 | } |
