summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIván Briano <ivan.briano@intel.com>2017-07-13 12:46:58 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-14 11:20:28 -0400
commitccd4eb49f3392ebf989d58bd013a7bf44cdca4d6 (patch)
tree11a5591bb0e15a09f49ce46d24b7161aaed750be /net
parent31a4562d7408493c6377933ff2f7d7302dbdea80 (diff)
net/packet: Fix Tx queue selection for AF_PACKET
When PACKET_QDISC_BYPASS is not used, Tx queue selection will be done before the packet is enqueued, taking into account any mappings set by a queuing discipline such as mqprio without hardware offloading. This selection may be affected by a previously saved queue_mapping, either on the Rx path, or done before the packet reaches the device, as it's currently the case for AF_PACKET. In order for queue selection to work as expected when using traffic control, there can't be another selection done before that point is reached, so move the call to packet_pick_tx_queue to packet_direct_xmit, leaving the default xmit path as it was before PACKET_QDISC_BYPASS was introduced. A forward declaration of packet_pick_tx_queue() is introduced to avoid the need to reorder the functions within the file. Fixes: d346a3fae3ff ("packet: introduce PACKET_QDISC_BYPASS socket option") Signed-off-by: Iván Briano <ivan.briano@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/packet/af_packet.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e3beb28203eb..008bb34ee324 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -214,6 +214,7 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *,
214static void prb_fill_vlan_info(struct tpacket_kbdq_core *, 214static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
215 struct tpacket3_hdr *); 215 struct tpacket3_hdr *);
216static void packet_flush_mclist(struct sock *sk); 216static void packet_flush_mclist(struct sock *sk);
217static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb);
217 218
218struct packet_skb_cb { 219struct packet_skb_cb {
219 union { 220 union {
@@ -260,6 +261,7 @@ static int packet_direct_xmit(struct sk_buff *skb)
260 if (skb != orig_skb) 261 if (skb != orig_skb)
261 goto drop; 262 goto drop;
262 263
264 packet_pick_tx_queue(dev, skb);
263 txq = skb_get_tx_queue(dev, skb); 265 txq = skb_get_tx_queue(dev, skb);
264 266
265 local_bh_disable(); 267 local_bh_disable();
@@ -2747,8 +2749,6 @@ tpacket_error:
2747 goto tpacket_error; 2749 goto tpacket_error;
2748 } 2750 }
2749 2751
2750 packet_pick_tx_queue(dev, skb);
2751
2752 skb->destructor = tpacket_destruct_skb; 2752 skb->destructor = tpacket_destruct_skb;
2753 __packet_set_status(po, ph, TP_STATUS_SENDING); 2753 __packet_set_status(po, ph, TP_STATUS_SENDING);
2754 packet_inc_pending(&po->tx_ring); 2754 packet_inc_pending(&po->tx_ring);
@@ -2931,8 +2931,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
2931 skb->priority = sk->sk_priority; 2931 skb->priority = sk->sk_priority;
2932 skb->mark = sockc.mark; 2932 skb->mark = sockc.mark;
2933 2933
2934 packet_pick_tx_queue(dev, skb);
2935
2936 if (po->has_vnet_hdr) { 2934 if (po->has_vnet_hdr) {
2937 err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le()); 2935 err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
2938 if (err) 2936 if (err)