Skip to content

Commit eadec87

Browse files
Alexander DuyckJeff Kirsher
authored andcommitted
net: Add support for subordinate traffic classes to netdev_pick_tx
This change makes it so that we can support the concept of subordinate device traffic classes to the core networking code. In doing this we can start pulling out the driver specific bits needed to support selecting a queue based on an upper device. The solution at is currently stands is only partially implemented. I have the start of some XPS bits in here, but I would still need to allow for configuration of the XPS maps on the queues reserved for the subordinate devices. For now I am using the reference to the sb_dev XPS map as just a way to skip the lookup of the lower device XPS map for now as that would result in the wrong queue being picked. Signed-off-by: Alexander Duyck <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 58b0b3e commit eadec87

File tree

4 files changed

+45
-46
lines changed

4 files changed

+45
-46
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8208,20 +8208,17 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
82088208
input, common, ring->queue_index);
82098209
}
82108210

8211+
#ifdef IXGBE_FCOE
82118212
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
82128213
void *accel_priv, select_queue_fallback_t fallback)
82138214
{
8214-
struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;
8215-
#ifdef IXGBE_FCOE
82168215
struct ixgbe_adapter *adapter;
82178216
struct ixgbe_ring_feature *f;
8218-
#endif
82198217
int txq;
82208218

8221-
if (fwd_adapter) {
8222-
u8 tc = netdev_get_num_tc(dev) ?
8223-
netdev_get_prio_tc_map(dev, skb->priority) : 0;
8224-
struct net_device *vdev = fwd_adapter->netdev;
8219+
if (accel_priv) {
8220+
u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
8221+
struct net_device *vdev = accel_priv;
82258222

82268223
txq = vdev->tc_to_txq[tc].offset;
82278224
txq += reciprocal_scale(skb_get_hash(skb),
@@ -8230,8 +8227,6 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
82308227
return txq;
82318228
}
82328229

8233-
#ifdef IXGBE_FCOE
8234-
82358230
/*
82368231
* only execute the code below if protocol is FCoE
82378232
* or FIP and we have FCoE enabled on the adapter
@@ -8257,11 +8252,9 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
82578252
txq -= f->indices;
82588253

82598254
return txq + f->offset;
8260-
#else
8261-
return fallback(dev, skb);
8262-
#endif
82638255
}
82648256

8257+
#endif
82658258
static int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
82668259
struct xdp_frame *xdpf)
82678260
{
@@ -10058,7 +10051,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
1005810051
.ndo_open = ixgbe_open,
1005910052
.ndo_stop = ixgbe_close,
1006010053
.ndo_start_xmit = ixgbe_xmit_frame,
10061-
.ndo_select_queue = ixgbe_select_queue,
1006210054
.ndo_set_rx_mode = ixgbe_set_rx_mode,
1006310055
.ndo_validate_addr = eth_validate_addr,
1006410056
.ndo_set_mac_address = ixgbe_set_mac,
@@ -10081,6 +10073,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
1008110073
.ndo_poll_controller = ixgbe_netpoll,
1008210074
#endif
1008310075
#ifdef IXGBE_FCOE
10076+
.ndo_select_queue = ixgbe_select_queue,
1008410077
.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
1008510078
.ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target,
1008610079
.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,

drivers/net/macvlan.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
514514
const struct macvlan_dev *vlan = netdev_priv(dev);
515515
const struct macvlan_port *port = vlan->port;
516516
const struct macvlan_dev *dest;
517-
void *accel_priv = NULL;
518517

519518
if (vlan->mode == MACVLAN_MODE_BRIDGE) {
520519
const struct ethhdr *eth = (void *)skb->data;
@@ -533,15 +532,10 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
533532
return NET_XMIT_SUCCESS;
534533
}
535534
}
536-
537-
/* For packets that are non-multicast and not bridged we will pass
538-
* the necessary information so that the lowerdev can distinguish
539-
* the source of the packets via the accel_priv value.
540-
*/
541-
accel_priv = vlan->accel_priv;
542535
xmit_world:
543536
skb->dev = vlan->lowerdev;
544-
return dev_queue_xmit_accel(skb, accel_priv);
537+
return dev_queue_xmit_accel(skb,
538+
netdev_get_sb_channel(dev) ? dev : NULL);
545539
}
546540

547541
static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, struct sk_buff *skb)

include/linux/netdevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,7 +2103,7 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev,
21032103

21042104
struct netdev_queue *netdev_pick_tx(struct net_device *dev,
21052105
struct sk_buff *skb,
2106-
void *accel_priv);
2106+
struct net_device *sb_dev);
21072107

21082108
/* returns the headroom that the master device needs to take in account
21092109
* when forwarding to this dev
@@ -2568,7 +2568,7 @@ void dev_close_many(struct list_head *head, bool unlink);
25682568
void dev_disable_lro(struct net_device *dev);
25692569
int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb);
25702570
int dev_queue_xmit(struct sk_buff *skb);
2571-
int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv);
2571+
int dev_queue_xmit_accel(struct sk_buff *skb, struct net_device *sb_dev);
25722572
int dev_direct_xmit(struct sk_buff *skb, u16 queue_id);
25732573
int register_netdevice(struct net_device *dev);
25742574
void unregister_netdevice_queue(struct net_device *dev, struct list_head *head);

net/core/dev.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,24 +2786,26 @@ EXPORT_SYMBOL(netif_device_attach);
27862786
* Returns a Tx hash based on the given packet descriptor a Tx queues' number
27872787
* to be used as a distribution range.
27882788
*/
2789-
static u16 skb_tx_hash(const struct net_device *dev, struct sk_buff *skb)
2789+
static u16 skb_tx_hash(const struct net_device *dev,
2790+
const struct net_device *sb_dev,
2791+
struct sk_buff *skb)
27902792
{
27912793
u32 hash;
27922794
u16 qoffset = 0;
27932795
u16 qcount = dev->real_num_tx_queues;
27942796

2797+
if (dev->num_tc) {
2798+
u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
2799+
2800+
qoffset = sb_dev->tc_to_txq[tc].offset;
2801+
qcount = sb_dev->tc_to_txq[tc].count;
2802+
}
2803+
27952804
if (skb_rx_queue_recorded(skb)) {
27962805
hash = skb_get_rx_queue(skb);
27972806
while (unlikely(hash >= qcount))
27982807
hash -= qcount;
2799-
return hash;
2800-
}
2801-
2802-
if (dev->num_tc) {
2803-
u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
2804-
2805-
qoffset = dev->tc_to_txq[tc].offset;
2806-
qcount = dev->tc_to_txq[tc].count;
2808+
return hash + qoffset;
28072809
}
28082810

28092811
return (u16) reciprocal_scale(skb_get_hash(skb), qcount) + qoffset;
@@ -3573,7 +3575,8 @@ static int __get_xps_queue_idx(struct net_device *dev, struct sk_buff *skb,
35733575
}
35743576
#endif
35753577

3576-
static int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
3578+
static int get_xps_queue(struct net_device *dev, struct net_device *sb_dev,
3579+
struct sk_buff *skb)
35773580
{
35783581
#ifdef CONFIG_XPS
35793582
struct xps_dev_maps *dev_maps;
@@ -3587,7 +3590,7 @@ static int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
35873590
if (!static_key_false(&xps_rxqs_needed))
35883591
goto get_cpus_map;
35893592

3590-
dev_maps = rcu_dereference(dev->xps_rxqs_map);
3593+
dev_maps = rcu_dereference(sb_dev->xps_rxqs_map);
35913594
if (dev_maps) {
35923595
int tci = sk_rx_queue_get(sk);
35933596

@@ -3598,7 +3601,7 @@ static int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
35983601

35993602
get_cpus_map:
36003603
if (queue_index < 0) {
3601-
dev_maps = rcu_dereference(dev->xps_cpus_map);
3604+
dev_maps = rcu_dereference(sb_dev->xps_cpus_map);
36023605
if (dev_maps) {
36033606
unsigned int tci = skb->sender_cpu - 1;
36043607

@@ -3614,17 +3617,20 @@ static int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
36143617
#endif
36153618
}
36163619

3617-
static u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb)
3620+
static u16 ___netdev_pick_tx(struct net_device *dev, struct sk_buff *skb,
3621+
struct net_device *sb_dev)
36183622
{
36193623
struct sock *sk = skb->sk;
36203624
int queue_index = sk_tx_queue_get(sk);
36213625

3626+
sb_dev = sb_dev ? : dev;
3627+
36223628
if (queue_index < 0 || skb->ooo_okay ||
36233629
queue_index >= dev->real_num_tx_queues) {
3624-
int new_index = get_xps_queue(dev, skb);
3630+
int new_index = get_xps_queue(dev, sb_dev, skb);
36253631

36263632
if (new_index < 0)
3627-
new_index = skb_tx_hash(dev, skb);
3633+
new_index = skb_tx_hash(dev, sb_dev, skb);
36283634

36293635
if (queue_index != new_index && sk &&
36303636
sk_fullsock(sk) &&
@@ -3637,9 +3643,15 @@ static u16 __netdev_pick_tx(struct net_device *dev, struct sk_buff *skb)
36373643
return queue_index;
36383644
}
36393645

3646+
static u16 __netdev_pick_tx(struct net_device *dev,
3647+
struct sk_buff *skb)
3648+
{
3649+
return ___netdev_pick_tx(dev, skb, NULL);
3650+
}
3651+
36403652
struct netdev_queue *netdev_pick_tx(struct net_device *dev,
36413653
struct sk_buff *skb,
3642-
void *accel_priv)
3654+
struct net_device *sb_dev)
36433655
{
36443656
int queue_index = 0;
36453657

@@ -3654,10 +3666,10 @@ struct netdev_queue *netdev_pick_tx(struct net_device *dev,
36543666
const struct net_device_ops *ops = dev->netdev_ops;
36553667

36563668
if (ops->ndo_select_queue)
3657-
queue_index = ops->ndo_select_queue(dev, skb, accel_priv,
3669+
queue_index = ops->ndo_select_queue(dev, skb, sb_dev,
36583670
__netdev_pick_tx);
36593671
else
3660-
queue_index = __netdev_pick_tx(dev, skb);
3672+
queue_index = ___netdev_pick_tx(dev, skb, sb_dev);
36613673

36623674
queue_index = netdev_cap_txqueue(dev, queue_index);
36633675
}
@@ -3669,7 +3681,7 @@ struct netdev_queue *netdev_pick_tx(struct net_device *dev,
36693681
/**
36703682
* __dev_queue_xmit - transmit a buffer
36713683
* @skb: buffer to transmit
3672-
* @accel_priv: private data used for L2 forwarding offload
3684+
* @sb_dev: suboordinate device used for L2 forwarding offload
36733685
*
36743686
* Queue a buffer for transmission to a network device. The caller must
36753687
* have set the device and priority and built the buffer before calling
@@ -3692,7 +3704,7 @@ struct netdev_queue *netdev_pick_tx(struct net_device *dev,
36923704
* the BH enable code must have IRQs enabled so that it will not deadlock.
36933705
* --BLG
36943706
*/
3695-
static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
3707+
static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
36963708
{
36973709
struct net_device *dev = skb->dev;
36983710
struct netdev_queue *txq;
@@ -3731,7 +3743,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
37313743
else
37323744
skb_dst_force(skb);
37333745

3734-
txq = netdev_pick_tx(dev, skb, accel_priv);
3746+
txq = netdev_pick_tx(dev, skb, sb_dev);
37353747
q = rcu_dereference_bh(txq->qdisc);
37363748

37373749
trace_net_dev_queue(skb);
@@ -3805,9 +3817,9 @@ int dev_queue_xmit(struct sk_buff *skb)
38053817
}
38063818
EXPORT_SYMBOL(dev_queue_xmit);
38073819

3808-
int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv)
3820+
int dev_queue_xmit_accel(struct sk_buff *skb, struct net_device *sb_dev)
38093821
{
3810-
return __dev_queue_xmit(skb, accel_priv);
3822+
return __dev_queue_xmit(skb, sb_dev);
38113823
}
38123824
EXPORT_SYMBOL(dev_queue_xmit_accel);
38133825

0 commit comments

Comments
 (0)