diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9a253faefc81..ca406157724c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -273,10 +273,10 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, | |||
273 | __u32 tstamp) | 273 | __u32 tstamp) |
274 | { | 274 | { |
275 | if (tp->rx_opt.tstamp_ok) { | 275 | if (tp->rx_opt.tstamp_ok) { |
276 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | 276 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
277 | (TCPOPT_NOP << 16) | | 277 | (TCPOPT_NOP << 16) | |
278 | (TCPOPT_TIMESTAMP << 8) | | 278 | (TCPOPT_TIMESTAMP << 8) | |
279 | TCPOLEN_TIMESTAMP); | 279 | TCPOLEN_TIMESTAMP); |
280 | *ptr++ = htonl(tstamp); | 280 | *ptr++ = htonl(tstamp); |
281 | *ptr++ = htonl(tp->rx_opt.ts_recent); | 281 | *ptr++ = htonl(tp->rx_opt.ts_recent); |
282 | } | 282 | } |
@@ -325,18 +325,27 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack, | |||
325 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | 325 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); |
326 | if (ts) { | 326 | if (ts) { |
327 | if(sack) | 327 | if(sack) |
328 | *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | | 328 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | |
329 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 329 | (TCPOLEN_SACK_PERM << 16) | |
330 | (TCPOPT_TIMESTAMP << 8) | | ||
331 | TCPOLEN_TIMESTAMP); | ||
330 | else | 332 | else |
331 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 333 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
332 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | 334 | (TCPOPT_NOP << 16) | |
335 | (TCPOPT_TIMESTAMP << 8) | | ||
336 | TCPOLEN_TIMESTAMP); | ||
333 | *ptr++ = htonl(tstamp); /* TSVAL */ | 337 | *ptr++ = htonl(tstamp); /* TSVAL */ |
334 | *ptr++ = htonl(ts_recent); /* TSECR */ | 338 | *ptr++ = htonl(ts_recent); /* TSECR */ |
335 | } else if(sack) | 339 | } else if(sack) |
336 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 340 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
337 | (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); | 341 | (TCPOPT_NOP << 16) | |
342 | (TCPOPT_SACK_PERM << 8) | | ||
343 | TCPOLEN_SACK_PERM); | ||
338 | if (offer_wscale) | 344 | if (offer_wscale) |
339 | *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); | 345 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
346 | (TCPOPT_WINDOW << 16) | | ||
347 | (TCPOLEN_WINDOW << 8) | | ||
348 | (wscale)); | ||
340 | } | 349 | } |
341 | 350 | ||
342 | /* This routine actually transmits TCP packets queued in by | 351 | /* This routine actually transmits TCP packets queued in by |
@@ -1087,10 +1096,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1087 | u32 send_win, cong_win, limit, in_flight; | 1096 | u32 send_win, cong_win, limit, in_flight; |
1088 | 1097 | ||
1089 | if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) | 1098 | if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) |
1090 | return 0; | 1099 | goto send_now; |
1091 | 1100 | ||
1092 | if (icsk->icsk_ca_state != TCP_CA_Open) | 1101 | if (icsk->icsk_ca_state != TCP_CA_Open) |
1093 | return 0; | 1102 | goto send_now; |
1103 | |||
1104 | /* Defer for less than two clock ticks. */ | ||
1105 | if (!tp->tso_deferred && ((jiffies<<1)>>1) - (tp->tso_deferred>>1) > 1) | ||
1106 | goto send_now; | ||
1094 | 1107 | ||
1095 | in_flight = tcp_packets_in_flight(tp); | 1108 | in_flight = tcp_packets_in_flight(tp); |
1096 | 1109 | ||
@@ -1106,7 +1119,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1106 | 1119 | ||
1107 | /* If a full-sized TSO skb can be sent, do it. */ | 1120 | /* If a full-sized TSO skb can be sent, do it. */ |
1108 | if (limit >= 65536) | 1121 | if (limit >= 65536) |
1109 | return 0; | 1122 | goto send_now; |
1110 | 1123 | ||
1111 | if (sysctl_tcp_tso_win_divisor) { | 1124 | if (sysctl_tcp_tso_win_divisor) { |
1112 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1125 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
@@ -1116,7 +1129,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1116 | */ | 1129 | */ |
1117 | chunk /= sysctl_tcp_tso_win_divisor; | 1130 | chunk /= sysctl_tcp_tso_win_divisor; |
1118 | if (limit >= chunk) | 1131 | if (limit >= chunk) |
1119 | return 0; | 1132 | goto send_now; |
1120 | } else { | 1133 | } else { |
1121 | /* Different approach, try not to defer past a single | 1134 | /* Different approach, try not to defer past a single |
1122 | * ACK. Receiver should ACK every other full sized | 1135 | * ACK. Receiver should ACK every other full sized |
@@ -1124,11 +1137,17 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
1124 | * then send now. | 1137 | * then send now. |
1125 | */ | 1138 | */ |
1126 | if (limit > tcp_max_burst(tp) * tp->mss_cache) | 1139 | if (limit > tcp_max_burst(tp) * tp->mss_cache) |
1127 | return 0; | 1140 | goto send_now; |
1128 | } | 1141 | } |
1129 | 1142 | ||
1130 | /* Ok, it looks like it is advisable to defer. */ | 1143 | /* Ok, it looks like it is advisable to defer. */ |
1144 | tp->tso_deferred = 1 | (jiffies<<1); | ||
1145 | |||
1131 | return 1; | 1146 | return 1; |
1147 | |||
1148 | send_now: | ||
1149 | tp->tso_deferred = 0; | ||
1150 | return 0; | ||
1132 | } | 1151 | } |
1133 | 1152 | ||
1134 | /* Create a new MTU probe if we are ready. | 1153 | /* Create a new MTU probe if we are ready. |