Skip to content

Commit 3853b58

Browse files
Tom Herbertdavem330
authored andcommitted
xps: Improvements in TX queue selection
In dev_pick_tx, don't do work in calculating queue index or setting the index in the sock unless the device has more than one queue. This allows the sock to be set only with a queue index of a multi-queue device which is desirable if device are stacked like in a tunnel. We also allow the mapping of a socket to queue to be changed. To maintain in order packet transmission a flag (ooo_okay) has been added to the sk_buff structure. If a transport layer sets this flag on a packet, the transmit queue can be changed for the socket. Presumably, the transport would set this if there was no possbility of creating OOO packets (for instance, there are no packets in flight for the socket). This patch includes the modification in TCP output for setting this flag. Signed-off-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 22f4fbd commit 3853b58

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

include/linux/skbuff.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,10 @@ struct sk_buff {
386386
#else
387387
__u8 deliver_no_wcard:1;
388388
#endif
389+
__u8 ooo_okay:1;
389390
kmemcheck_bitfield_end(flags2);
390391

391-
/* 0/14 bit hole */
392+
/* 0/13 bit hole */
392393

393394
#ifdef CONFIG_NET_DMA
394395
dma_cookie_t dma_cookie;

net/core/dev.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,20 +2148,24 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
21482148
int queue_index;
21492149
const struct net_device_ops *ops = dev->netdev_ops;
21502150

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) {
21522154
queue_index = ops->ndo_select_queue(dev, skb);
21532155
queue_index = dev_cap_txqueue(dev, queue_index);
21542156
} else {
21552157
struct sock *sk = skb->sk;
21562158
queue_index = sk_tx_queue_get(sk);
2157-
if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) {
21582159

2159-
queue_index = 0;
2160-
if (dev->real_num_tx_queues > 1)
2161-
queue_index = skb_tx_hash(dev, skb);
2160+
if (queue_index < 0 || skb->ooo_okay ||
2161+
queue_index >= dev->real_num_tx_queues) {
2162+
int old_index = queue_index;
21622163

2163-
if (sk) {
2164-
struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1);
2164+
queue_index = skb_tx_hash(dev, skb);
2165+
2166+
if (queue_index != old_index && sk) {
2167+
struct dst_entry *dst =
2168+
rcu_dereference_check(sk->sk_dst_cache, 1);
21652169

21662170
if (dst && skb_dst(skb) == dst)
21672171
sk_tx_queue_set(sk, queue_index);

net/ipv4/tcp_output.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
822822
&md5);
823823
tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
824824

825-
if (tcp_packets_in_flight(tp) == 0)
825+
if (tcp_packets_in_flight(tp) == 0) {
826826
tcp_ca_event(sk, CA_EVENT_TX_START);
827+
skb->ooo_okay = 1;
828+
} else
829+
skb->ooo_okay = 0;
827830

828831
skb_push(skb, tcp_header_size);
829832
skb_reset_transport_header(skb);

0 commit comments

Comments
 (0)