aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2014-10-10 21:06:35 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-14 13:12:00 -0400
commitb2532eb9abd88384aa586169b54a3e53574f29f8 (patch)
treef46795756a2b89adab83759a4e47befd8ba8aba6 /net/ipv4/tcp_output.c
parent31eff81e94472ddb7549509bf4b6e93e1f6f7dc9 (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>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c8
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);