Commit 4f81def2 authored by Pavan Chebbi's avatar Pavan Chebbi Committed by David S. Miller
Browse files

bnxt_en: Synchronize tx when xdp redirects happen on same ring



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: f18c2b77 ("bnxt_en: optimized XDP_REDIRECT support")
Signed-off-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 20921c0c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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 */
+2 −0
Original line number Diff line number Diff line
@@ -800,6 +800,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					\
+8 −0
Original line number Diff line number Diff line
@@ -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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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);