Skip to content

Commit

Permalink
Merge branch 'net-refactor-ndo_select_queue'
Browse files Browse the repository at this point in the history
Paolo Abeni says:

====================
net: refactor ndo_select_queue()

Currently, on most devices implementing ndo_select_queue(), we get 2
indirect calls per xmit packet, at least in some scenarios.

We can avoid one of such indirect calls refactoring the ndo_select_queue()
usage so that we don't need anymore the 'fallback' argument.

The first patch renames a helper used later as a public API, the second one
changes the af packet implementation so that it uses the common infrastructure
to select the xmit queue, and the second patch drops the now unneeded argument
from ndo_select_queue().

Alternatively we could use the INDIRECT_CALL_WRAPPER infrastructure to avoid
the fallback indirect call in the common case, but this solution allows also
for some code cleanup.

 v1 -> v2:
  - renamed select queue helpers, as per Eric's and David's suggestions
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 20, 2019
2 parents 0b963ef + a350ecc commit 75d317c
Show file tree
Hide file tree
Showing 34 changed files with 79 additions and 117 deletions.
3 changes: 1 addition & 2 deletions drivers/infiniband/hw/hfi1/vnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,7 @@ static netdev_tx_t hfi1_netdev_start_xmit(struct sk_buff *skb,

static u16 hfi1_vnic_select_queue(struct net_device *netdev,
struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev);
struct opa_vnic_skb_mdata *mdata;
Expand Down
6 changes: 2 additions & 4 deletions drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ static netdev_tx_t opa_netdev_start_xmit(struct sk_buff *skb,
}

static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev);
struct opa_vnic_skb_mdata *mdata;
Expand All @@ -106,8 +105,7 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,
mdata = skb_push(skb, sizeof(*mdata));
mdata->entropy = opa_vnic_calc_entropy(skb);
mdata->vl = opa_vnic_get_vl(adapter, skb);
rc = adapter->rn_ops->ndo_select_queue(netdev, skb,
sb_dev, fallback);
rc = adapter->rn_ops->ndo_select_queue(netdev, skb, sb_dev);
skb_pull(skb, sizeof(*mdata));
return rc;
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4114,8 +4114,7 @@ static inline int bond_slave_override(struct bonding *bond,


static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
/* This helper function exists to help dev_pick_tx get the correct
* destination queue. Using a helper function skips a call to
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/amazon/ena/ena_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2258,8 +2258,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
}

static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
u16 qid;
/* we suspect that this is good for in--kernel network services that
Expand All @@ -2269,7 +2268,7 @@ static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
if (skb_rx_queue_recorded(skb))
qid = skb_get_rx_queue(skb);
else
qid = fallback(dev, skb, NULL);
qid = netdev_pick_tx(dev, skb, NULL);

return qid;
}
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/ethernet/broadcom/bcmsysport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2274,24 +2274,23 @@ static const struct ethtool_ops bcm_sysport_ethtool_ops = {
};

static u16 bcm_sysport_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
u16 queue = skb_get_queue_mapping(skb);
struct bcm_sysport_tx_ring *tx_ring;
unsigned int q, port;

if (!netdev_uses_dsa(dev))
return fallback(dev, skb, NULL);
return netdev_pick_tx(dev, skb, NULL);

/* DSA tagging layer will have configured the correct queue */
q = BRCM_TAG_GET_QUEUE(queue);
port = BRCM_TAG_GET_PORT(queue);
tx_ring = priv->ring_map[q + port * priv->per_port_num_tx_queues];

if (unlikely(!tx_ring))
return fallback(dev, skb, NULL);
return netdev_pick_tx(dev, skb, NULL);

return tx_ring->index;
}
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1909,8 +1909,7 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
}

u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct bnx2x *bp = netdev_priv(dev);

Expand All @@ -1932,7 +1931,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
}

/* select a non-FCoE queue */
return fallback(dev, skb, NULL) %
return netdev_pick_tx(dev, skb, NULL) %
(BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
}

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,7 @@ int bnx2x_set_vf_spoofchk(struct net_device *dev, int idx, bool val);

/* select_queue callback */
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback);
struct net_device *sb_dev);

static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
struct bnx2x_fastpath *fp,
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,8 +979,7 @@ static int setup_sge_queues(struct adapter *adap)
}

static u16 cxgb_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
int txq;

Expand Down Expand Up @@ -1022,7 +1021,7 @@ static u16 cxgb_select_queue(struct net_device *dev, struct sk_buff *skb,
return txq;
}

return fallback(dev, skb, NULL) % dev->real_num_tx_queues;
return netdev_pick_tx(dev, skb, NULL) % dev->real_num_tx_queues;
}

static int closest_timer(const struct sge *s, int time)
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/hisilicon/hns/hns_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1964,8 +1964,7 @@ static void hns_nic_get_stats64(struct net_device *ndev,

static u16
hns_nic_select_queue(struct net_device *ndev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;
struct hns_nic_priv *priv = netdev_priv(ndev);
Expand All @@ -1975,7 +1974,7 @@ hns_nic_select_queue(struct net_device *ndev, struct sk_buff *skb,
is_multicast_ether_addr(eth_hdr->h_dest))
return 0;
else
return fallback(ndev, skb, NULL);
return netdev_pick_tx(ndev, skb, NULL);
}

static const struct net_device_ops hns_nic_netdev_ops = {
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8483,8 +8483,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring,

#ifdef IXGBE_FCOE
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct ixgbe_adapter *adapter;
struct ixgbe_ring_feature *f;
Expand Down Expand Up @@ -8514,7 +8513,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
break;
/* fall through */
default:
return fallback(dev, skb, sb_dev);
return netdev_pick_tx(dev, skb, sb_dev);
}

f = &adapter->ring_feature[RING_F_FCOE];
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/ethernet/mellanox/mlx4/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,16 +685,15 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc,
}

u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
u16 rings_p_up = priv->num_tx_rings_p_up;

if (netdev_get_num_tc(dev))
return fallback(dev, skb, NULL);
return netdev_pick_tx(dev, skb, NULL);

return fallback(dev, skb, NULL) % rings_p_up;
return netdev_pick_tx(dev, skb, NULL) % rings_p_up;
}

static void mlx4_bf_copy(void __iomem *dst, const void *src,
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,7 @@ void mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);

void mlx4_en_tx_irq(struct mlx4_cq *mcq);
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback);
struct net_device *sb_dev);
netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
netdev_tx_t mlx4_en_xmit_frame(struct mlx4_en_rx_ring *rx_ring,
struct mlx4_en_rx_alloc *frame,
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,8 +769,7 @@ struct mlx5e_profile {
void mlx5e_build_ptys2ethtool_map(void);

u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback);
struct net_device *sb_dev);
netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
struct mlx5e_tx_wqe *wqe, u16 pi);
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
#endif

u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
int channel_ix = netdev_pick_tx(dev, skb, NULL);
struct mlx5e_priv *priv = netdev_priv(dev);
int channel_ix = fallback(dev, skb, NULL);
u16 num_channels;
int up = 0;

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/qlogic/qede/qede.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,7 @@ struct qede_reload_args {
/* Datapath functions definition */
netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev);
u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback);
struct net_device *sb_dev);
netdev_features_t qede_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features);
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/qlogic/qede/qede_fp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1696,16 +1696,15 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}

u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct qede_dev *edev = netdev_priv(dev);
int total_txq;

total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc;

return QEDE_TSS_COUNT(edev) ?
fallback(dev, skb, NULL) % total_txq : 0;
netdev_pick_tx(dev, skb, NULL) % total_txq : 0;
}

/* 8B udp header + 8B base tunnel header + 32B option length */
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/renesas/ravb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1615,8 +1615,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}

static u16 ravb_select_queue(struct net_device *ndev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
/* If skb needs TX timestamp, it is handled in network control queue */
return (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) ? RAVB_NC :
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/sun/ldmvsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ static struct vnet_port *vsw_tx_port_find(struct sk_buff *skb,
}

static u16 vsw_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct vnet_port *port = netdev_priv(dev);

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/sun/sunvnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ static struct vnet_port *vnet_tx_port_find(struct sk_buff *skb,
}

static u16 vnet_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct vnet *vp = netdev_priv(dev);
struct vnet_port *port = __tx_port_find(vp, skb);
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/hyperv/netvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ static inline int netvsc_get_tx_queue(struct net_device *ndev,
* If a valid queue has already been assigned, then use that.
* Otherwise compute tx queue based on hash and the send table.
*
* This is basically similar to default (__netdev_pick_tx) with the added step
* This is basically similar to default (netdev_pick_tx) with the added step
* of using the host send_table when no other queue has been assigned.
*
* TODO support XPS - but get_xps_queue not exported
Expand All @@ -331,8 +331,7 @@ static u16 netvsc_pick_tx(struct net_device *ndev, struct sk_buff *skb)
}

static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct net_device_context *ndc = netdev_priv(ndev);
struct net_device *vf_netdev;
Expand All @@ -344,10 +343,9 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
const struct net_device_ops *vf_ops = vf_netdev->netdev_ops;

if (vf_ops->ndo_select_queue)
txq = vf_ops->ndo_select_queue(vf_netdev, skb,
sb_dev, fallback);
txq = vf_ops->ndo_select_queue(vf_netdev, skb, sb_dev);
else
txq = fallback(vf_netdev, skb, NULL);
txq = netdev_pick_tx(vf_netdev, skb, NULL);

/* Record the queue selected by VF so that it can be
* used for common case where VF has more queues than
Expand Down
8 changes: 3 additions & 5 deletions drivers/net/net_failover.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ static netdev_tx_t net_failover_start_xmit(struct sk_buff *skb,

static u16 net_failover_select_queue(struct net_device *dev,
struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct net_failover_info *nfo_info = netdev_priv(dev);
struct net_device *primary_dev;
Expand All @@ -127,10 +126,9 @@ static u16 net_failover_select_queue(struct net_device *dev,
const struct net_device_ops *ops = primary_dev->netdev_ops;

if (ops->ndo_select_queue)
txq = ops->ndo_select_queue(primary_dev, skb,
sb_dev, fallback);
txq = ops->ndo_select_queue(primary_dev, skb, sb_dev);
else
txq = fallback(primary_dev, skb, NULL);
txq = netdev_pick_tx(primary_dev, skb, NULL);

qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/team/team.c
Original file line number Diff line number Diff line change
Expand Up @@ -1691,8 +1691,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev)
}

static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
/*
* This helper function exists to help dev_pick_tx get the correct
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,7 @@ static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb)
}

static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct tun_struct *tun = netdev_priv(dev);
u16 ret;
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/marvell/mwifiex/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,8 +1282,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)

static u16
mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
skb->priority = cfg80211_classify8021d(skb, NULL);
return mwifiex_1d_to_wmm_queue[skb->priority];
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/xen-netback/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@ void xenvif_wake_queue(struct xenvif_queue *queue)
}

static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
struct net_device *sb_dev)
{
struct xenvif *vif = netdev_priv(dev);
unsigned int size = vif->hash.size;
Expand All @@ -162,7 +161,8 @@ static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,
return 0;

if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
return fallback(dev, skb, NULL) % dev->real_num_tx_queues;
return netdev_pick_tx(dev, skb, NULL) %
dev->real_num_tx_queues;

xenvif_set_skb_hash(vif, skb);

Expand Down
Loading

0 comments on commit 75d317c

Please sign in to comment.