|
@@ -895,8 +895,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
|
|
|
|
|
|
skb_orphan(skb);
|
|
|
skb->sk = sk;
|
|
|
- skb->destructor = (sysctl_tcp_limit_output_bytes > 0) ?
|
|
|
- tcp_wfree : sock_wfree;
|
|
|
+ skb->destructor = tcp_wfree;
|
|
|
atomic_add(skb->truesize, &sk->sk_wmem_alloc);
|
|
|
|
|
|
/* Build TCP header and checksum it. */
|
|
@@ -1840,7 +1839,6 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|
|
while ((skb = tcp_send_head(sk))) {
|
|
|
unsigned int limit;
|
|
|
|
|
|
-
|
|
|
tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
|
|
|
BUG_ON(!tso_segs);
|
|
|
|
|
@@ -1869,13 +1867,20 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- /* TSQ : sk_wmem_alloc accounts skb truesize,
|
|
|
- * including skb overhead. But thats OK.
|
|
|
+ /* TCP Small Queues :
|
|
|
+ * Control number of packets in qdisc/devices to two packets / or ~1 ms.
|
|
|
+ * This allows for :
|
|
|
+ * - better RTT estimation and ACK scheduling
|
|
|
+ * - faster recovery
|
|
|
+ * - high rates
|
|
|
*/
|
|
|
- if (atomic_read(&sk->sk_wmem_alloc) >= sysctl_tcp_limit_output_bytes) {
|
|
|
+ limit = max(skb->truesize, sk->sk_pacing_rate >> 10);
|
|
|
+
|
|
|
+ if (atomic_read(&sk->sk_wmem_alloc) > limit) {
|
|
|
set_bit(TSQ_THROTTLED, &tp->tsq_flags);
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
limit = mss_now;
|
|
|
if (tso_segs > 1 && !tcp_urg_mode(tp))
|
|
|
limit = tcp_mss_split_point(sk, skb, mss_now,
|