diff options
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 882436da9a3a..ddb6ce4ecff2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -615,7 +615,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse | |||
| 615 | size_t psize, int flags) | 615 | size_t psize, int flags) |
| 616 | { | 616 | { |
| 617 | struct tcp_sock *tp = tcp_sk(sk); | 617 | struct tcp_sock *tp = tcp_sk(sk); |
| 618 | int mss_now; | 618 | int mss_now, size_goal; |
| 619 | int err; | 619 | int err; |
| 620 | ssize_t copied; | 620 | ssize_t copied; |
| 621 | long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); | 621 | long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); |
| @@ -628,6 +628,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse | |||
| 628 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 628 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
| 629 | 629 | ||
| 630 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 630 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); |
| 631 | size_goal = tp->xmit_size_goal; | ||
| 631 | copied = 0; | 632 | copied = 0; |
| 632 | 633 | ||
| 633 | err = -EPIPE; | 634 | err = -EPIPE; |
| @@ -641,7 +642,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse | |||
| 641 | int offset = poffset % PAGE_SIZE; | 642 | int offset = poffset % PAGE_SIZE; |
| 642 | int size = min_t(size_t, psize, PAGE_SIZE - offset); | 643 | int size = min_t(size_t, psize, PAGE_SIZE - offset); |
| 643 | 644 | ||
| 644 | if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { | 645 | if (!sk->sk_send_head || (copy = size_goal - skb->len) <= 0) { |
| 645 | new_segment: | 646 | new_segment: |
| 646 | if (!sk_stream_memory_free(sk)) | 647 | if (!sk_stream_memory_free(sk)) |
| 647 | goto wait_for_sndbuf; | 648 | goto wait_for_sndbuf; |
| @@ -652,7 +653,7 @@ new_segment: | |||
| 652 | goto wait_for_memory; | 653 | goto wait_for_memory; |
| 653 | 654 | ||
| 654 | skb_entail(sk, tp, skb); | 655 | skb_entail(sk, tp, skb); |
| 655 | copy = mss_now; | 656 | copy = size_goal; |
| 656 | } | 657 | } |
| 657 | 658 | ||
| 658 | if (copy > size) | 659 | if (copy > size) |
| @@ -693,7 +694,7 @@ new_segment: | |||
| 693 | if (!(psize -= copy)) | 694 | if (!(psize -= copy)) |
| 694 | goto out; | 695 | goto out; |
| 695 | 696 | ||
| 696 | if (skb->len != mss_now || (flags & MSG_OOB)) | 697 | if (skb->len < mss_now || (flags & MSG_OOB)) |
| 697 | continue; | 698 | continue; |
| 698 | 699 | ||
| 699 | if (forced_push(tp)) { | 700 | if (forced_push(tp)) { |
| @@ -713,6 +714,7 @@ wait_for_memory: | |||
| 713 | goto do_error; | 714 | goto do_error; |
| 714 | 715 | ||
| 715 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 716 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); |
| 717 | size_goal = tp->xmit_size_goal; | ||
| 716 | } | 718 | } |
| 717 | 719 | ||
| 718 | out: | 720 | out: |
| @@ -754,15 +756,20 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, | |||
| 754 | 756 | ||
| 755 | static inline int select_size(struct sock *sk, struct tcp_sock *tp) | 757 | static inline int select_size(struct sock *sk, struct tcp_sock *tp) |
| 756 | { | 758 | { |
| 757 | int tmp = tp->mss_cache_std; | 759 | int tmp = tp->mss_cache; |
| 758 | 760 | ||
| 759 | if (sk->sk_route_caps & NETIF_F_SG) { | 761 | if (sk->sk_route_caps & NETIF_F_SG) { |
| 760 | int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); | 762 | if (sk->sk_route_caps & NETIF_F_TSO) |
| 763 | tmp = 0; | ||
| 764 | else { | ||
| 765 | int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); | ||
| 761 | 766 | ||
| 762 | if (tmp >= pgbreak && | 767 | if (tmp >= pgbreak && |
| 763 | tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) | 768 | tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) |
| 764 | tmp = pgbreak; | 769 | tmp = pgbreak; |
| 770 | } | ||
| 765 | } | 771 | } |
| 772 | |||
| 766 | return tmp; | 773 | return tmp; |
| 767 | } | 774 | } |
| 768 | 775 | ||
| @@ -773,7 +780,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 773 | struct tcp_sock *tp = tcp_sk(sk); | 780 | struct tcp_sock *tp = tcp_sk(sk); |
| 774 | struct sk_buff *skb; | 781 | struct sk_buff *skb; |
| 775 | int iovlen, flags; | 782 | int iovlen, flags; |
| 776 | int mss_now; | 783 | int mss_now, size_goal; |
| 777 | int err, copied; | 784 | int err, copied; |
| 778 | long timeo; | 785 | long timeo; |
| 779 | 786 | ||
| @@ -792,6 +799,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 792 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 799 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
| 793 | 800 | ||
| 794 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 801 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); |
| 802 | size_goal = tp->xmit_size_goal; | ||
| 795 | 803 | ||
| 796 | /* Ok commence sending. */ | 804 | /* Ok commence sending. */ |
| 797 | iovlen = msg->msg_iovlen; | 805 | iovlen = msg->msg_iovlen; |
| @@ -814,7 +822,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 814 | skb = sk->sk_write_queue.prev; | 822 | skb = sk->sk_write_queue.prev; |
| 815 | 823 | ||
| 816 | if (!sk->sk_send_head || | 824 | if (!sk->sk_send_head || |
| 817 | (copy = mss_now - skb->len) <= 0) { | 825 | (copy = size_goal - skb->len) <= 0) { |
| 818 | 826 | ||
| 819 | new_segment: | 827 | new_segment: |
| 820 | /* Allocate new segment. If the interface is SG, | 828 | /* Allocate new segment. If the interface is SG, |
| @@ -837,7 +845,7 @@ new_segment: | |||
| 837 | skb->ip_summed = CHECKSUM_HW; | 845 | skb->ip_summed = CHECKSUM_HW; |
| 838 | 846 | ||
| 839 | skb_entail(sk, tp, skb); | 847 | skb_entail(sk, tp, skb); |
| 840 | copy = mss_now; | 848 | copy = size_goal; |
| 841 | } | 849 | } |
| 842 | 850 | ||
| 843 | /* Try to append data to the end of skb. */ | 851 | /* Try to append data to the end of skb. */ |
| @@ -872,11 +880,6 @@ new_segment: | |||
| 872 | tcp_mark_push(tp, skb); | 880 | tcp_mark_push(tp, skb); |
| 873 | goto new_segment; | 881 | goto new_segment; |
| 874 | } else if (page) { | 882 | } else if (page) { |
| 875 | /* If page is cached, align | ||
| 876 | * offset to L1 cache boundary | ||
| 877 | */ | ||
| 878 | off = (off + L1_CACHE_BYTES - 1) & | ||
| 879 | ~(L1_CACHE_BYTES - 1); | ||
| 880 | if (off == PAGE_SIZE) { | 883 | if (off == PAGE_SIZE) { |
| 881 | put_page(page); | 884 | put_page(page); |
| 882 | TCP_PAGE(sk) = page = NULL; | 885 | TCP_PAGE(sk) = page = NULL; |
| @@ -937,7 +940,7 @@ new_segment: | |||
| 937 | if ((seglen -= copy) == 0 && iovlen == 0) | 940 | if ((seglen -= copy) == 0 && iovlen == 0) |
| 938 | goto out; | 941 | goto out; |
| 939 | 942 | ||
| 940 | if (skb->len != mss_now || (flags & MSG_OOB)) | 943 | if (skb->len < mss_now || (flags & MSG_OOB)) |
| 941 | continue; | 944 | continue; |
| 942 | 945 | ||
| 943 | if (forced_push(tp)) { | 946 | if (forced_push(tp)) { |
| @@ -957,6 +960,7 @@ wait_for_memory: | |||
| 957 | goto do_error; | 960 | goto do_error; |
| 958 | 961 | ||
| 959 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 962 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); |
| 963 | size_goal = tp->xmit_size_goal; | ||
| 960 | } | 964 | } |
| 961 | } | 965 | } |
| 962 | 966 | ||
| @@ -1101,7 +1105,7 @@ static void tcp_prequeue_process(struct sock *sk) | |||
| 1101 | struct sk_buff *skb; | 1105 | struct sk_buff *skb; |
| 1102 | struct tcp_sock *tp = tcp_sk(sk); | 1106 | struct tcp_sock *tp = tcp_sk(sk); |
| 1103 | 1107 | ||
| 1104 | NET_ADD_STATS_USER(LINUX_MIB_TCPPREQUEUED, skb_queue_len(&tp->ucopy.prequeue)); | 1108 | NET_INC_STATS_USER(LINUX_MIB_TCPPREQUEUED); |
| 1105 | 1109 | ||
| 1106 | /* RX process wants to run with disabled BHs, though it is not | 1110 | /* RX process wants to run with disabled BHs, though it is not |
| 1107 | * necessary */ | 1111 | * necessary */ |
| @@ -1365,7 +1369,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1365 | * is not empty. It is more elegant, but eats cycles, | 1369 | * is not empty. It is more elegant, but eats cycles, |
| 1366 | * unfortunately. | 1370 | * unfortunately. |
| 1367 | */ | 1371 | */ |
| 1368 | if (skb_queue_len(&tp->ucopy.prequeue)) | 1372 | if (!skb_queue_empty(&tp->ucopy.prequeue)) |
| 1369 | goto do_prequeue; | 1373 | goto do_prequeue; |
| 1370 | 1374 | ||
| 1371 | /* __ Set realtime policy in scheduler __ */ | 1375 | /* __ Set realtime policy in scheduler __ */ |
| @@ -1390,7 +1394,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1390 | } | 1394 | } |
| 1391 | 1395 | ||
| 1392 | if (tp->rcv_nxt == tp->copied_seq && | 1396 | if (tp->rcv_nxt == tp->copied_seq && |
| 1393 | skb_queue_len(&tp->ucopy.prequeue)) { | 1397 | !skb_queue_empty(&tp->ucopy.prequeue)) { |
| 1394 | do_prequeue: | 1398 | do_prequeue: |
| 1395 | tcp_prequeue_process(sk); | 1399 | tcp_prequeue_process(sk); |
| 1396 | 1400 | ||
| @@ -1472,7 +1476,7 @@ skip_copy: | |||
| 1472 | } while (len > 0); | 1476 | } while (len > 0); |
| 1473 | 1477 | ||
| 1474 | if (user_recv) { | 1478 | if (user_recv) { |
| 1475 | if (skb_queue_len(&tp->ucopy.prequeue)) { | 1479 | if (!skb_queue_empty(&tp->ucopy.prequeue)) { |
| 1476 | int chunk; | 1480 | int chunk; |
| 1477 | 1481 | ||
| 1478 | tp->ucopy.len = copied > 0 ? len : 0; | 1482 | tp->ucopy.len = copied > 0 ? len : 0; |
| @@ -2128,7 +2132,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
| 2128 | 2132 | ||
| 2129 | info->tcpi_rto = jiffies_to_usecs(tp->rto); | 2133 | info->tcpi_rto = jiffies_to_usecs(tp->rto); |
| 2130 | info->tcpi_ato = jiffies_to_usecs(tp->ack.ato); | 2134 | info->tcpi_ato = jiffies_to_usecs(tp->ack.ato); |
| 2131 | info->tcpi_snd_mss = tp->mss_cache_std; | 2135 | info->tcpi_snd_mss = tp->mss_cache; |
| 2132 | info->tcpi_rcv_mss = tp->ack.rcv_mss; | 2136 | info->tcpi_rcv_mss = tp->ack.rcv_mss; |
| 2133 | 2137 | ||
| 2134 | info->tcpi_unacked = tp->packets_out; | 2138 | info->tcpi_unacked = tp->packets_out; |
| @@ -2178,7 +2182,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
| 2178 | 2182 | ||
| 2179 | switch (optname) { | 2183 | switch (optname) { |
| 2180 | case TCP_MAXSEG: | 2184 | case TCP_MAXSEG: |
| 2181 | val = tp->mss_cache_std; | 2185 | val = tp->mss_cache; |
| 2182 | if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) | 2186 | if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) |
| 2183 | val = tp->rx_opt.user_mss; | 2187 | val = tp->rx_opt.user_mss; |
| 2184 | break; | 2188 | break; |
