diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index d3f9beee74c0..886596ff0aae 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -661,6 +661,37 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp) | |||
661 | return NULL; | 661 | return NULL; |
662 | } | 662 | } |
663 | 663 | ||
664 | static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, | ||
665 | int large_allowed) | ||
666 | { | ||
667 | struct tcp_sock *tp = tcp_sk(sk); | ||
668 | u32 xmit_size_goal; | ||
669 | |||
670 | xmit_size_goal = mss_now; | ||
671 | |||
672 | if (large_allowed && sk_can_gso(sk)) { | ||
673 | xmit_size_goal = ((sk->sk_gso_max_size - 1) - | ||
674 | inet_csk(sk)->icsk_af_ops->net_header_len - | ||
675 | inet_csk(sk)->icsk_ext_hdr_len - | ||
676 | tp->tcp_header_len); | ||
677 | |||
678 | xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal); | ||
679 | xmit_size_goal -= (xmit_size_goal % mss_now); | ||
680 | } | ||
681 | |||
682 | return xmit_size_goal; | ||
683 | } | ||
684 | |||
685 | static int tcp_send_mss(struct sock *sk, int *size_goal, int flags) | ||
686 | { | ||
687 | int mss_now; | ||
688 | |||
689 | mss_now = tcp_current_mss(sk); | ||
690 | *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); | ||
691 | |||
692 | return mss_now; | ||
693 | } | ||
694 | |||
664 | static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, | 695 | static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, |
665 | size_t psize, int flags) | 696 | size_t psize, int flags) |
666 | { | 697 | { |
@@ -677,8 +708,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse | |||
677 | 708 | ||
678 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 709 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
679 | 710 | ||
680 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 711 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
681 | size_goal = tp->xmit_size_goal; | ||
682 | copied = 0; | 712 | copied = 0; |
683 | 713 | ||
684 | err = -EPIPE; | 714 | err = -EPIPE; |
@@ -761,8 +791,7 @@ wait_for_memory: | |||
761 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) | 791 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) |
762 | goto do_error; | 792 | goto do_error; |
763 | 793 | ||
764 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 794 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
765 | size_goal = tp->xmit_size_goal; | ||
766 | } | 795 | } |
767 | 796 | ||
768 | out: | 797 | out: |
@@ -844,8 +873,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
844 | /* This should be in poll */ | 873 | /* This should be in poll */ |
845 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 874 | clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
846 | 875 | ||
847 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 876 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
848 | size_goal = tp->xmit_size_goal; | ||
849 | 877 | ||
850 | /* Ok commence sending. */ | 878 | /* Ok commence sending. */ |
851 | iovlen = msg->msg_iovlen; | 879 | iovlen = msg->msg_iovlen; |
@@ -1007,8 +1035,7 @@ wait_for_memory: | |||
1007 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) | 1035 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) |
1008 | goto do_error; | 1036 | goto do_error; |
1009 | 1037 | ||
1010 | mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); | 1038 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
1011 | size_goal = tp->xmit_size_goal; | ||
1012 | } | 1039 | } |
1013 | } | 1040 | } |
1014 | 1041 | ||