Merge branch 'bnxt_en-fixes'

Michael Chan says:

====================
bnxt_en: XDP redirect fixes

This series includes 3 fixes related to the XDP redirect code path in
the driver.  The first one adds locking when the number of TX XDP rings
is less than the number of CPUs.  The second one adjusts the maximum MTU
that can support XDP with enough tail room in the buffer.  The 3rd one
fixes a race condition between TX ring shutdown and the XDP redirect path.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2022-04-04 12:44:50 +01:00
commit 5dc64b6dcb
4 changed files with 25 additions and 3 deletions

View file

@ -3253,6 +3253,7 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
}
qidx = bp->tc_to_qidx[j];
ring->queue_id = bp->q_info[qidx].queue_id;
spin_lock_init(&txr->xdp_tx_lock);
if (i < bp->tx_nr_rings_xdp)
continue;
if (i % bp->tx_nr_rings_per_tc == (bp->tx_nr_rings_per_tc - 1))
@ -10338,6 +10339,12 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
if (irq_re_init)
udp_tunnel_nic_reset_ntf(bp->dev);
if (bp->tx_nr_rings_xdp < num_possible_cpus()) {
if (!static_key_enabled(&bnxt_xdp_locking_key))
static_branch_enable(&bnxt_xdp_locking_key);
} else if (static_key_enabled(&bnxt_xdp_locking_key)) {
static_branch_disable(&bnxt_xdp_locking_key);
}
set_bit(BNXT_STATE_OPEN, &bp->state);
bnxt_enable_int(bp);
/* Enable TX queues */

View file

@ -593,7 +593,8 @@ struct nqe_cn {
#define BNXT_MAX_MTU 9500
#define BNXT_MAX_PAGE_MODE_MTU \
((unsigned int)PAGE_SIZE - VLAN_ETH_HLEN - NET_IP_ALIGN - \
XDP_PACKET_HEADROOM)
XDP_PACKET_HEADROOM - \
SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info)))
#define BNXT_MIN_PKT_SIZE 52
@ -800,6 +801,8 @@ struct bnxt_tx_ring_info {
u32 dev_state;
struct bnxt_ring_struct tx_ring_struct;
/* Synchronize simultaneous xdp_xmit on same ring */
spinlock_t xdp_tx_lock;
};
#define BNXT_LEGACY_COAL_CMPL_PARAMS \

View file

@ -20,6 +20,8 @@
#include "bnxt.h"
#include "bnxt_xdp.h"
DEFINE_STATIC_KEY_FALSE(bnxt_xdp_locking_key);
struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
struct bnxt_tx_ring_info *txr,
dma_addr_t mapping, u32 len)
@ -227,11 +229,16 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
ring = smp_processor_id() % bp->tx_nr_rings_xdp;
txr = &bp->tx_ring[ring];
if (READ_ONCE(txr->dev_state) == BNXT_DEV_STATE_CLOSING)
return -EINVAL;
if (static_branch_unlikely(&bnxt_xdp_locking_key))
spin_lock(&txr->xdp_tx_lock);
for (i = 0; i < num_frames; i++) {
struct xdp_frame *xdp = frames[i];
if (!txr || !bnxt_tx_avail(bp, txr) ||
!(bp->bnapi[ring]->flags & BNXT_NAPI_FLAG_XDP))
if (!bnxt_tx_avail(bp, txr))
break;
mapping = dma_map_single(&pdev->dev, xdp->data, xdp->len,
@ -250,6 +257,9 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
bnxt_db_write(bp, &txr->tx_db, txr->tx_prod);
}
if (static_branch_unlikely(&bnxt_xdp_locking_key))
spin_unlock(&txr->xdp_tx_lock);
return nxmit;
}

View file

@ -10,6 +10,8 @@
#ifndef BNXT_XDP_H
#define BNXT_XDP_H
DECLARE_STATIC_KEY_FALSE(bnxt_xdp_locking_key);
struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
struct bnxt_tx_ring_info *txr,
dma_addr_t mapping, u32 len);