diff options
author | Eric Dumazet <edumazet@google.com> | 2014-10-10 21:06:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-14 13:12:00 -0400 |
commit | b2532eb9abd88384aa586169b54a3e53574f29f8 (patch) | |
tree | f46795756a2b89adab83759a4e47befd8ba8aba6 | |
parent | 31eff81e94472ddb7549509bf4b6e93e1f6f7dc9 (diff) |
tcp: fix ooo_okay setting vs Small Queues
TCP Small Queues (tcp_tsq_handler()) can hold one reference on
sk->sk_wmem_alloc, preventing skb->ooo_okay being set.
We should relax test done to set skb->ooo_okay to take care
of this extra reference.
Minimal truesize of skb containing one byte of payload is
SKB_TRUESIZE(1)
Without this fix, we have more chance locking flows into the wrong
transmit queue.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/tcp_output.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8d4eac793700..0a5d97c20aa9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -914,9 +914,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
914 | tcp_ca_event(sk, CA_EVENT_TX_START); | 914 | tcp_ca_event(sk, CA_EVENT_TX_START); |
915 | 915 | ||
916 | /* if no packet is in qdisc/device queue, then allow XPS to select | 916 | /* if no packet is in qdisc/device queue, then allow XPS to select |
917 | * another queue. | 917 | * another queue. We can be called from tcp_tsq_handler() |
918 | * which holds one reference to sk_wmem_alloc. | ||
919 | * | ||
920 | * TODO: Ideally, in-flight pure ACK packets should not matter here. | ||
921 | * One way to get this would be to set skb->truesize = 2 on them. | ||
918 | */ | 922 | */ |
919 | skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; | 923 | skb->ooo_okay = sk_wmem_alloc_get(sk) < SKB_TRUESIZE(1); |
920 | 924 | ||
921 | skb_push(skb, tcp_header_size); | 925 | skb_push(skb, tcp_header_size); |
922 | skb_reset_transport_header(skb); | 926 | skb_reset_transport_header(skb); |