bnxt_en: Synchronize tx when xdp redirects happen on same ring
[ Upstream commit 4f81def272de17dc4bbd89ac38f49b2676c9b3d2 ] If there are more CPUs than the number of TX XDP rings, multiple XDP redirects can select the same TX ring based on the CPU on which XDP redirect is called. Add locking when needed and use static key to decide whether to take the lock. Fixes: f18c2b77b2e4 ("bnxt_en: optimized XDP_REDIRECT support") Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
87f5d66daa
commit
6108a8918f
@ -3234,6 +3234,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))
|
||||
@ -10246,6 +10247,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 */
|
||||
|
@ -791,6 +791,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 \
|
||||
|
@ -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,6 +229,9 @@ 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 (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];
|
||||
|
||||
@ -250,6 +255,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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user