Skip to content

Commit

Permalink
Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/jkirsher/next-queue

Jeff Kirsher says:

====================
L2 Fwd Offload & 10GbE Intel Driver Updates 2018-07-09

This patch series is meant to allow support for the L2 forward offload, aka
MACVLAN offload without the need for using ndo_select_queue.

The existing solution currently requires that we use ndo_select_queue in
the transmit path if we want to associate specific Tx queues with a given
MACVLAN interface. In order to get away from this we need to repurpose the
tc_to_txq array and XPS pointer for the MACVLAN interface and use those as
a means of accessing the queues on the lower device. As a result we cannot
offload a device that is configured as multiqueue, however it doesn't
really make sense to configure a macvlan interfaced as being multiqueue
anyway since it doesn't really have a qdisc of its own in the first place.

The big changes in this set are:
  Allow lower device to update tc_to_txq and XPS map of offloaded MACVLAN
  Disable XPS for single queue devices
  Replace accel_priv with sb_dev in ndo_select_queue
  Add sb_dev parameter to fallback function for ndo_select_queue
  Consolidated ndo_select_queue functions that appeared to be duplicates
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 12, 2018
2 parents 4929c94 + 8ec56fc commit e32f55f
Show file tree
Hide file tree
Showing 35 changed files with 312 additions and 131 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/hfi1/vnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +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,
void *accel_priv,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev);
Expand Down
4 changes: 2 additions & 2 deletions drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +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,
void *accel_priv,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev);
Expand All @@ -107,7 +107,7 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,
mdata->entropy = opa_vnic_calc_entropy(skb);
mdata->vl = opa_vnic_get_vl(adapter, skb);
rc = adapter->rn_ops->ndo_select_queue(netdev, skb,
accel_priv, fallback);
sb_dev, fallback);
skb_pull(skb, sizeof(*mdata));
return rc;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4094,7 +4094,8 @@ static inline int bond_slave_override(struct bonding *bond,


static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
/* 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: 3 additions & 2 deletions drivers/net/ethernet/amazon/ena/ena_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2213,7 +2213,8 @@ static void ena_netpoll(struct net_device *netdev)
#endif /* CONFIG_NET_POLL_CONTROLLER */

static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
u16 qid;
/* we suspect that this is good for in--kernel network services that
Expand All @@ -2223,7 +2224,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);
qid = fallback(dev, skb, NULL);

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

static u16 bcm_sysport_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv,
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
Expand All @@ -2116,15 +2116,15 @@ static u16 bcm_sysport_select_queue(struct net_device *dev, struct sk_buff *skb,
unsigned int q, port;

if (!netdev_uses_dsa(dev))
return fallback(dev, skb);
return fallback(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);
return fallback(dev, skb, NULL);

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

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

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

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

void bnx2x_set_num_queues(struct bnx2x *bp)
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,8 @@ int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,

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

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

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

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

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

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

static u16
hns_nic_select_queue(struct net_device *ndev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;
struct hns_nic_priv *priv = netdev_priv(ndev);
Expand All @@ -2032,7 +2033,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);
return fallback(ndev, skb, NULL);
}

static const struct net_device_ops hns_nic_netdev_ops = {
Expand Down
62 changes: 44 additions & 18 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5275,6 +5275,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
static int ixgbe_fwd_ring_up(struct ixgbe_adapter *adapter,
struct ixgbe_fwd_adapter *accel)
{
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices;
int num_tc = netdev_get_num_tc(adapter->netdev);
struct net_device *vdev = accel->netdev;
int i, baseq, err;

Expand All @@ -5286,6 +5288,11 @@ static int ixgbe_fwd_ring_up(struct ixgbe_adapter *adapter,
accel->rx_base_queue = baseq;
accel->tx_base_queue = baseq;

/* record configuration for macvlan interface in vdev */
for (i = 0; i < num_tc; i++)
netdev_bind_sb_channel_queue(adapter->netdev, vdev,
i, rss_i, baseq + (rss_i * i));

for (i = 0; i < adapter->num_rx_queues_per_pool; i++)
adapter->rx_ring[baseq + i]->netdev = vdev;

Expand All @@ -5310,6 +5317,10 @@ static int ixgbe_fwd_ring_up(struct ixgbe_adapter *adapter,

netdev_err(vdev, "L2FW offload disabled due to L2 filter error\n");

/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(adapter->netdev, vdev);
netdev_set_sb_channel(vdev, 0);

clear_bit(accel->pool, adapter->fwd_bitmask);
kfree(accel);

Expand Down Expand Up @@ -8197,25 +8208,25 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
input, common, ring->queue_index);
}

#ifdef IXGBE_FCOE
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;
struct ixgbe_adapter *adapter;
int txq;
#ifdef IXGBE_FCOE
struct ixgbe_ring_feature *f;
#endif
int txq;

if (fwd_adapter) {
adapter = netdev_priv(dev);
txq = reciprocal_scale(skb_get_hash(skb),
adapter->num_rx_queues_per_pool);
if (sb_dev) {
u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
struct net_device *vdev = sb_dev;

return txq + fwd_adapter->tx_base_queue;
}
txq = vdev->tc_to_txq[tc].offset;
txq += reciprocal_scale(skb_get_hash(skb),
vdev->tc_to_txq[tc].count);

#ifdef IXGBE_FCOE
return txq;
}

/*
* only execute the code below if protocol is FCoE
Expand All @@ -8226,11 +8237,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
case htons(ETH_P_FIP):
adapter = netdev_priv(dev);

if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
if (!sb_dev && (adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
break;
/* fall through */
default:
return fallback(dev, skb);
return fallback(dev, skb, sb_dev);
}

f = &adapter->ring_feature[RING_F_FCOE];
Expand All @@ -8242,11 +8253,9 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
txq -= f->indices;

return txq + f->offset;
#else
return fallback(dev, skb);
#endif
}

#endif
static int ixgbe_xmit_xdp_ring(struct ixgbe_adapter *adapter,
struct xdp_frame *xdpf)
{
Expand Down Expand Up @@ -8766,6 +8775,11 @@ static int ixgbe_reassign_macvlan_pool(struct net_device *vdev, void *data)
/* if we cannot find a free pool then disable the offload */
netdev_err(vdev, "L2FW offload disabled due to lack of queue resources\n");
macvlan_release_l2fw_offload(vdev);

/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(adapter->netdev, vdev);
netdev_set_sb_channel(vdev, 0);

kfree(accel);

return 0;
Expand Down Expand Up @@ -9769,6 +9783,13 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
if (!macvlan_supports_dest_filter(vdev))
return ERR_PTR(-EMEDIUMTYPE);

/* We need to lock down the macvlan to be a single queue device so that
* we can reuse the tc_to_txq field in the macvlan netdev to represent
* the queue mapping to our netdev.
*/
if (netif_is_multiqueue(vdev))
return ERR_PTR(-ERANGE);

pool = find_first_zero_bit(adapter->fwd_bitmask, adapter->num_rx_pools);
if (pool == adapter->num_rx_pools) {
u16 used_pools = adapter->num_vfs + adapter->num_rx_pools;
Expand Down Expand Up @@ -9825,6 +9846,7 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
return ERR_PTR(-ENOMEM);

set_bit(pool, adapter->fwd_bitmask);
netdev_set_sb_channel(vdev, pool);
accel->pool = pool;
accel->netdev = vdev;

Expand Down Expand Up @@ -9866,6 +9888,10 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
ring->netdev = NULL;
}

/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(pdev, accel->netdev);
netdev_set_sb_channel(accel->netdev, 0);

clear_bit(accel->pool, adapter->fwd_bitmask);
kfree(accel);
}
Expand Down Expand Up @@ -10026,7 +10052,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
.ndo_select_queue = ixgbe_select_queue,
.ndo_set_rx_mode = ixgbe_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ixgbe_set_mac,
Expand All @@ -10049,6 +10074,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_poll_controller = ixgbe_netpoll,
#endif
#ifdef IXGBE_FCOE
.ndo_select_queue = ixgbe_select_queue,
.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
.ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target,
.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
Expand Down
10 changes: 1 addition & 9 deletions drivers/net/ethernet/lantiq_etop.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,14 +563,6 @@ ltq_etop_set_multicast_list(struct net_device *dev)
spin_unlock_irqrestore(&priv->lock, flags);
}

static u16
ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
{
/* we are currently only using the first queue */
return 0;
}

static int
ltq_etop_init(struct net_device *dev)
{
Expand Down Expand Up @@ -641,7 +633,7 @@ static const struct net_device_ops ltq_eth_netdev_ops = {
.ndo_set_mac_address = ltq_etop_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = ltq_etop_set_multicast_list,
.ndo_select_queue = ltq_etop_select_queue,
.ndo_select_queue = dev_pick_tx_zero,
.ndo_init = ltq_etop_init,
.ndo_tx_timeout = ltq_etop_tx_timeout,
};
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/mellanox/mlx4/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,15 +688,16 @@ 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,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
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);
return fallback(dev, skb, NULL);

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

static void mlx4_bf_copy(void __iomem *dst, const void *src,
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,8 @@ 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,
void *accel_priv, select_queue_fallback_t fallback);
struct net_device *sb_dev,
select_queue_fallback_t fallback);
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: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,8 @@ struct mlx5e_profile {
void mlx5e_build_ptys2ethtool_map(void);

u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback);
struct net_device *sb_dev,
select_queue_fallback_t fallback);
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: 3 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@ 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,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
struct mlx5e_priv *priv = netdev_priv(dev);
int channel_ix = fallback(dev, skb);
int channel_ix = fallback(dev, skb, NULL);
u16 num_channels;
int up = 0;

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/renesas/ravb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1656,7 +1656,8 @@ 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,
void *accel_priv, select_queue_fallback_t fallback)
struct net_device *sb_dev,
select_queue_fallback_t fallback)
{
/* 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
Loading

0 comments on commit e32f55f

Please sign in to comment.