aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/net/tcp.h13
-rw-r--r--net/ipv4/tcp.c43
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv4/tcp_output.c41
5 files changed, 54 insertions, 46 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 4b86ad71e054..ad2021ccc55a 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -248,7 +248,6 @@ struct tcp_sock {
248 /* inet_connection_sock has to be the first member of tcp_sock */ 248 /* inet_connection_sock has to be the first member of tcp_sock */
249 struct inet_connection_sock inet_conn; 249 struct inet_connection_sock inet_conn;
250 u16 tcp_header_len; /* Bytes of tcp header to send */ 250 u16 tcp_header_len; /* Bytes of tcp header to send */
251 u16 xmit_size_goal; /* Goal for segmenting output packets */
252 251
253/* 252/*
254 * Header prediction flags 253 * Header prediction flags
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 255ca35bea05..e54c76d75495 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -481,7 +481,16 @@ static inline void tcp_clear_xmit_timers(struct sock *sk)
481} 481}
482 482
483extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu); 483extern unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
484extern unsigned int tcp_current_mss(struct sock *sk, int large); 484extern unsigned int tcp_current_mss(struct sock *sk);
485
486/* Bound MSS / TSO packet size with the half of the window */
487static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
488{
489 if (tp->max_window && pktsize > (tp->max_window >> 1))
490 return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
491 else
492 return pktsize;
493}
485 494
486/* tcp.c */ 495/* tcp.c */
487extern void tcp_get_info(struct sock *, struct tcp_info *); 496extern void tcp_get_info(struct sock *, struct tcp_info *);
@@ -822,7 +831,7 @@ static inline void tcp_push_pending_frames(struct sock *sk)
822{ 831{
823 struct tcp_sock *tp = tcp_sk(sk); 832 struct tcp_sock *tp = tcp_sk(sk);
824 833
825 __tcp_push_pending_frames(sk, tcp_current_mss(sk, 1), tp->nonagle); 834 __tcp_push_pending_frames(sk, tcp_current_mss(sk), tp->nonagle);
826} 835}
827 836
828static inline void tcp_init_wl(struct tcp_sock *tp, u32 seq) 837static inline void tcp_init_wl(struct tcp_sock *tp, u32 seq)
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
664static 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
685static 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
664static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, 695static 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
768out: 797out:
@@ -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
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 311c30f73ee4..fae78e3eccc4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2864,7 +2864,7 @@ void tcp_simple_retransmit(struct sock *sk)
2864 const struct inet_connection_sock *icsk = inet_csk(sk); 2864 const struct inet_connection_sock *icsk = inet_csk(sk);
2865 struct tcp_sock *tp = tcp_sk(sk); 2865 struct tcp_sock *tp = tcp_sk(sk);
2866 struct sk_buff *skb; 2866 struct sk_buff *skb;
2867 unsigned int mss = tcp_current_mss(sk, 0); 2867 unsigned int mss = tcp_current_mss(sk);
2868 u32 prior_lost = tp->lost_out; 2868 u32 prior_lost = tp->lost_out;
2869 2869
2870 tcp_for_write_queue(skb, sk) { 2870 tcp_for_write_queue(skb, sk) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 325658039139..c1f259d2d33b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -921,7 +921,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
921 * factor and mss. 921 * factor and mss.
922 */ 922 */
923 if (tcp_skb_pcount(skb) > 1) 923 if (tcp_skb_pcount(skb) > 1)
924 tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk, 1)); 924 tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk));
925 925
926 return 0; 926 return 0;
927} 927}
@@ -982,15 +982,6 @@ void tcp_mtup_init(struct sock *sk)
982 icsk->icsk_mtup.probe_size = 0; 982 icsk->icsk_mtup.probe_size = 0;
983} 983}
984 984
985/* Bound MSS / TSO packet size with the half of the window */
986static int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
987{
988 if (tp->max_window && pktsize > (tp->max_window >> 1))
989 return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
990 else
991 return pktsize;
992}
993
994/* This function synchronize snd mss to current pmtu/exthdr set. 985/* This function synchronize snd mss to current pmtu/exthdr set.
995 986
996 tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts 987 tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
@@ -1037,22 +1028,17 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
1037/* Compute the current effective MSS, taking SACKs and IP options, 1028/* Compute the current effective MSS, taking SACKs and IP options,
1038 * and even PMTU discovery events into account. 1029 * and even PMTU discovery events into account.
1039 */ 1030 */
1040unsigned int tcp_current_mss(struct sock *sk, int large_allowed) 1031unsigned int tcp_current_mss(struct sock *sk)
1041{ 1032{
1042 struct tcp_sock *tp = tcp_sk(sk); 1033 struct tcp_sock *tp = tcp_sk(sk);
1043 struct dst_entry *dst = __sk_dst_get(sk); 1034 struct dst_entry *dst = __sk_dst_get(sk);
1044 u32 mss_now; 1035 u32 mss_now;
1045 u16 xmit_size_goal;
1046 int doing_tso = 0;
1047 unsigned header_len; 1036 unsigned header_len;
1048 struct tcp_out_options opts; 1037 struct tcp_out_options opts;
1049 struct tcp_md5sig_key *md5; 1038 struct tcp_md5sig_key *md5;
1050 1039
1051 mss_now = tp->mss_cache; 1040 mss_now = tp->mss_cache;
1052 1041
1053 if (large_allowed && sk_can_gso(sk))
1054 doing_tso = 1;
1055
1056 if (dst) { 1042 if (dst) {
1057 u32 mtu = dst_mtu(dst); 1043 u32 mtu = dst_mtu(dst);
1058 if (mtu != inet_csk(sk)->icsk_pmtu_cookie) 1044 if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
@@ -1070,19 +1056,6 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
1070 mss_now -= delta; 1056 mss_now -= delta;
1071 } 1057 }
1072 1058
1073 xmit_size_goal = mss_now;
1074
1075 if (doing_tso) {
1076 xmit_size_goal = ((sk->sk_gso_max_size - 1) -
1077 inet_csk(sk)->icsk_af_ops->net_header_len -
1078 inet_csk(sk)->icsk_ext_hdr_len -
1079 tp->tcp_header_len);
1080
1081 xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
1082 xmit_size_goal -= (xmit_size_goal % mss_now);
1083 }
1084 tp->xmit_size_goal = xmit_size_goal;
1085
1086 return mss_now; 1059 return mss_now;
1087} 1060}
1088 1061
@@ -1264,7 +1237,7 @@ int tcp_may_send_now(struct sock *sk)
1264 struct sk_buff *skb = tcp_send_head(sk); 1237 struct sk_buff *skb = tcp_send_head(sk);
1265 1238
1266 return (skb && 1239 return (skb &&
1267 tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), 1240 tcp_snd_test(sk, skb, tcp_current_mss(sk),
1268 (tcp_skb_is_last(sk, skb) ? 1241 (tcp_skb_is_last(sk, skb) ?
1269 tp->nonagle : TCP_NAGLE_PUSH))); 1242 tp->nonagle : TCP_NAGLE_PUSH)));
1270} 1243}
@@ -1421,7 +1394,7 @@ static int tcp_mtu_probe(struct sock *sk)
1421 return -1; 1394 return -1;
1422 1395
1423 /* Very simple search strategy: just double the MSS. */ 1396 /* Very simple search strategy: just double the MSS. */
1424 mss_now = tcp_current_mss(sk, 0); 1397 mss_now = tcp_current_mss(sk);
1425 probe_size = 2 * tp->mss_cache; 1398 probe_size = 2 * tp->mss_cache;
1426 size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache; 1399 size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
1427 if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) { 1400 if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
@@ -1903,7 +1876,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1903 if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) 1876 if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
1904 return -EHOSTUNREACH; /* Routing failure or similar. */ 1877 return -EHOSTUNREACH; /* Routing failure or similar. */
1905 1878
1906 cur_mss = tcp_current_mss(sk, 0); 1879 cur_mss = tcp_current_mss(sk);
1907 1880
1908 /* If receiver has shrunk his window, and skb is out of 1881 /* If receiver has shrunk his window, and skb is out of
1909 * new window, do not retransmit it. The exception is the 1882 * new window, do not retransmit it. The exception is the
@@ -2111,7 +2084,7 @@ void tcp_send_fin(struct sock *sk)
2111 * unsent frames. But be careful about outgoing SACKS 2084 * unsent frames. But be careful about outgoing SACKS
2112 * and IP options. 2085 * and IP options.
2113 */ 2086 */
2114 mss_now = tcp_current_mss(sk, 1); 2087 mss_now = tcp_current_mss(sk);
2115 2088
2116 if (tcp_send_head(sk) != NULL) { 2089 if (tcp_send_head(sk) != NULL) {
2117 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN; 2090 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
@@ -2523,7 +2496,7 @@ int tcp_write_wakeup(struct sock *sk)
2523 if ((skb = tcp_send_head(sk)) != NULL && 2496 if ((skb = tcp_send_head(sk)) != NULL &&
2524 before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))) { 2497 before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))) {
2525 int err; 2498 int err;
2526 unsigned int mss = tcp_current_mss(sk, 0); 2499 unsigned int mss = tcp_current_mss(sk);
2527 unsigned int seg_size = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq; 2500 unsigned int seg_size = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
2528 2501
2529 if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) 2502 if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq))