diff options
-rw-r--r-- | include/linux/skbuff.h | 3 | ||||
-rw-r--r-- | net/core/dev.c | 18 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 5 |
3 files changed, 17 insertions, 9 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e6ba898de61c..19f37a6ee6c4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -386,9 +386,10 @@ struct sk_buff { | |||
386 | #else | 386 | #else |
387 | __u8 deliver_no_wcard:1; | 387 | __u8 deliver_no_wcard:1; |
388 | #endif | 388 | #endif |
389 | __u8 ooo_okay:1; | ||
389 | kmemcheck_bitfield_end(flags2); | 390 | kmemcheck_bitfield_end(flags2); |
390 | 391 | ||
391 | /* 0/14 bit hole */ | 392 | /* 0/13 bit hole */ |
392 | 393 | ||
393 | #ifdef CONFIG_NET_DMA | 394 | #ifdef CONFIG_NET_DMA |
394 | dma_cookie_t dma_cookie; | 395 | dma_cookie_t dma_cookie; |
diff --git a/net/core/dev.c b/net/core/dev.c index 381b8e280162..7b17674a29ec 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2148,20 +2148,24 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2148 | int queue_index; | 2148 | int queue_index; |
2149 | const struct net_device_ops *ops = dev->netdev_ops; | 2149 | const struct net_device_ops *ops = dev->netdev_ops; |
2150 | 2150 | ||
2151 | if (ops->ndo_select_queue) { | 2151 | if (dev->real_num_tx_queues == 1) |
2152 | queue_index = 0; | ||
2153 | else if (ops->ndo_select_queue) { | ||
2152 | queue_index = ops->ndo_select_queue(dev, skb); | 2154 | queue_index = ops->ndo_select_queue(dev, skb); |
2153 | queue_index = dev_cap_txqueue(dev, queue_index); | 2155 | queue_index = dev_cap_txqueue(dev, queue_index); |
2154 | } else { | 2156 | } else { |
2155 | struct sock *sk = skb->sk; | 2157 | struct sock *sk = skb->sk; |
2156 | queue_index = sk_tx_queue_get(sk); | 2158 | queue_index = sk_tx_queue_get(sk); |
2157 | if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) { | ||
2158 | 2159 | ||
2159 | queue_index = 0; | 2160 | if (queue_index < 0 || skb->ooo_okay || |
2160 | if (dev->real_num_tx_queues > 1) | 2161 | queue_index >= dev->real_num_tx_queues) { |
2161 | queue_index = skb_tx_hash(dev, skb); | 2162 | int old_index = queue_index; |
2162 | 2163 | ||
2163 | if (sk) { | 2164 | queue_index = skb_tx_hash(dev, skb); |
2164 | struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1); | 2165 | |
2166 | if (queue_index != old_index && sk) { | ||
2167 | struct dst_entry *dst = | ||
2168 | rcu_dereference_check(sk->sk_dst_cache, 1); | ||
2165 | 2169 | ||
2166 | if (dst && skb_dst(skb) == dst) | 2170 | if (dst && skb_dst(skb) == dst) |
2167 | sk_tx_queue_set(sk, queue_index); | 2171 | sk_tx_queue_set(sk, queue_index); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index bb8f547fc7d2..5f29b2e20e23 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -822,8 +822,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
822 | &md5); | 822 | &md5); |
823 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); | 823 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
824 | 824 | ||
825 | if (tcp_packets_in_flight(tp) == 0) | 825 | if (tcp_packets_in_flight(tp) == 0) { |
826 | tcp_ca_event(sk, CA_EVENT_TX_START); | 826 | tcp_ca_event(sk, CA_EVENT_TX_START); |
827 | skb->ooo_okay = 1; | ||
828 | } else | ||
829 | skb->ooo_okay = 0; | ||
827 | 830 | ||
828 | skb_push(skb, tcp_header_size); | 831 | skb_push(skb, tcp_header_size); |
829 | skb_reset_transport_header(skb); | 832 | skb_reset_transport_header(skb); |