diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/tcp.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8a3f05adb39b..d5d69ea8f249 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -876,12 +876,12 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, | |||
| 876 | #define TCP_PAGE(sk) (sk->sk_sndmsg_page) | 876 | #define TCP_PAGE(sk) (sk->sk_sndmsg_page) |
| 877 | #define TCP_OFF(sk) (sk->sk_sndmsg_off) | 877 | #define TCP_OFF(sk) (sk->sk_sndmsg_off) |
| 878 | 878 | ||
| 879 | static inline int select_size(struct sock *sk) | 879 | static inline int select_size(struct sock *sk, int sg) |
| 880 | { | 880 | { |
| 881 | struct tcp_sock *tp = tcp_sk(sk); | 881 | struct tcp_sock *tp = tcp_sk(sk); |
| 882 | int tmp = tp->mss_cache; | 882 | int tmp = tp->mss_cache; |
| 883 | 883 | ||
| 884 | if (sk->sk_route_caps & NETIF_F_SG) { | 884 | if (sg) { |
| 885 | if (sk_can_gso(sk)) | 885 | if (sk_can_gso(sk)) |
| 886 | tmp = 0; | 886 | tmp = 0; |
| 887 | else { | 887 | else { |
| @@ -905,7 +905,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 905 | struct sk_buff *skb; | 905 | struct sk_buff *skb; |
| 906 | int iovlen, flags; | 906 | int iovlen, flags; |
| 907 | int mss_now, size_goal; | 907 | int mss_now, size_goal; |
| 908 | int err, copied; | 908 | int sg, err, copied; |
| 909 | long timeo; | 909 | long timeo; |
| 910 | 910 | ||
| 911 | lock_sock(sk); | 911 | lock_sock(sk); |
| @@ -933,6 +933,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 933 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 933 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
| 934 | goto out_err; | 934 | goto out_err; |
| 935 | 935 | ||
| 936 | sg = sk->sk_route_caps & NETIF_F_SG; | ||
| 937 | |||
| 936 | while (--iovlen >= 0) { | 938 | while (--iovlen >= 0) { |
| 937 | int seglen = iov->iov_len; | 939 | int seglen = iov->iov_len; |
| 938 | unsigned char __user *from = iov->iov_base; | 940 | unsigned char __user *from = iov->iov_base; |
| @@ -958,8 +960,9 @@ new_segment: | |||
| 958 | if (!sk_stream_memory_free(sk)) | 960 | if (!sk_stream_memory_free(sk)) |
| 959 | goto wait_for_sndbuf; | 961 | goto wait_for_sndbuf; |
| 960 | 962 | ||
| 961 | skb = sk_stream_alloc_skb(sk, select_size(sk), | 963 | skb = sk_stream_alloc_skb(sk, |
| 962 | sk->sk_allocation); | 964 | select_size(sk, sg), |
| 965 | sk->sk_allocation); | ||
| 963 | if (!skb) | 966 | if (!skb) |
| 964 | goto wait_for_memory; | 967 | goto wait_for_memory; |
| 965 | 968 | ||
| @@ -996,9 +999,7 @@ new_segment: | |||
| 996 | /* We can extend the last page | 999 | /* We can extend the last page |
| 997 | * fragment. */ | 1000 | * fragment. */ |
| 998 | merge = 1; | 1001 | merge = 1; |
| 999 | } else if (i == MAX_SKB_FRAGS || | 1002 | } else if (i == MAX_SKB_FRAGS || !sg) { |
| 1000 | (!i && | ||
| 1001 | !(sk->sk_route_caps & NETIF_F_SG))) { | ||
| 1002 | /* Need to add new fragment and cannot | 1003 | /* Need to add new fragment and cannot |
| 1003 | * do this because interface is non-SG, | 1004 | * do this because interface is non-SG, |
| 1004 | * or because all the page slots are | 1005 | * or because all the page slots are |
