aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3ed6fc15815b..dd30dd137b74 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -861,7 +861,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
861 u16 flags; 861 u16 flags;
862 862
863 /* All of a TSO frame must be composed of paged data. */ 863 /* All of a TSO frame must be composed of paged data. */
864 BUG_ON(skb->len != skb->data_len); 864 if (skb->len != skb->data_len)
865 return tcp_fragment(sk, skb, len, mss_now);
865 866
866 buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC); 867 buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC);
867 if (unlikely(buff == NULL)) 868 if (unlikely(buff == NULL))
@@ -924,10 +925,6 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
924 925
925 limit = min(send_win, cong_win); 926 limit = min(send_win, cong_win);
926 927
927 /* If sk_send_head can be sent fully now, just do it. */
928 if (skb->len <= limit)
929 return 0;
930
931 if (sysctl_tcp_tso_win_divisor) { 928 if (sysctl_tcp_tso_win_divisor) {
932 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); 929 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
933 930
@@ -974,6 +971,8 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
974 971
975 sent_pkts = 0; 972 sent_pkts = 0;
976 while ((skb = sk->sk_send_head)) { 973 while ((skb = sk->sk_send_head)) {
974 unsigned int limit;
975
977 tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 976 tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
978 BUG_ON(!tso_segs); 977 BUG_ON(!tso_segs);
979 978
@@ -994,9 +993,10 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
994 break; 993 break;
995 } 994 }
996 995
996 limit = mss_now;
997 if (tso_segs > 1) { 997 if (tso_segs > 1) {
998 u32 limit = tcp_window_allows(tp, skb, 998 limit = tcp_window_allows(tp, skb,
999 mss_now, cwnd_quota); 999 mss_now, cwnd_quota);
1000 1000
1001 if (skb->len < limit) { 1001 if (skb->len < limit) {
1002 unsigned int trim = skb->len % mss_now; 1002 unsigned int trim = skb->len % mss_now;
@@ -1004,15 +1004,12 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
1004 if (trim) 1004 if (trim)
1005 limit = skb->len - trim; 1005 limit = skb->len - trim;
1006 } 1006 }
1007 if (skb->len > limit) {
1008 if (tso_fragment(sk, skb, limit, mss_now))
1009 break;
1010 }
1011 } else if (unlikely(skb->len > mss_now)) {
1012 if (unlikely(tcp_fragment(sk, skb, mss_now, mss_now)))
1013 break;
1014 } 1007 }
1015 1008
1009 if (skb->len > limit &&
1010 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1011 break;
1012
1016 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1013 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1017 1014
1018 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) 1015 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
@@ -1064,11 +1061,14 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
1064 cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH); 1061 cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
1065 1062
1066 if (likely(cwnd_quota)) { 1063 if (likely(cwnd_quota)) {
1064 unsigned int limit;
1065
1067 BUG_ON(!tso_segs); 1066 BUG_ON(!tso_segs);
1068 1067
1068 limit = mss_now;
1069 if (tso_segs > 1) { 1069 if (tso_segs > 1) {
1070 u32 limit = tcp_window_allows(tp, skb, 1070 limit = tcp_window_allows(tp, skb,
1071 mss_now, cwnd_quota); 1071 mss_now, cwnd_quota);
1072 1072
1073 if (skb->len < limit) { 1073 if (skb->len < limit) {
1074 unsigned int trim = skb->len % mss_now; 1074 unsigned int trim = skb->len % mss_now;
@@ -1076,15 +1076,12 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
1076 if (trim) 1076 if (trim)
1077 limit = skb->len - trim; 1077 limit = skb->len - trim;
1078 } 1078 }
1079 if (skb->len > limit) {
1080 if (unlikely(tso_fragment(sk, skb, limit, mss_now)))
1081 return;
1082 }
1083 } else if (unlikely(skb->len > mss_now)) {
1084 if (unlikely(tcp_fragment(sk, skb, mss_now, mss_now)))
1085 return;
1086 } 1079 }
1087 1080
1081 if (skb->len > limit &&
1082 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1083 return;
1084
1088 /* Send it out now. */ 1085 /* Send it out now. */
1089 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1086 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1090 1087