On Thu, Aug 22, 2024 at 09:42:07AM +0200, Kurt Kanzenbach wrote: > From: Sriram Yagnaraman <sriram.yagnaraman@xxxxxxxx> > > Always call igb_xdp_ring_update_tail() under __netif_tx_lock, add a comment > and lockdep assert to indicate that. This is needed to share the same TX > ring between XDP, XSK and slow paths. Furthermore, the current XDP > implementation is racy on tail updates. > > Fixes: 9cbc948b5a20 ("igb: add XDP support") > Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@xxxxxxxx> > [Kurt: Add lockdep assert and fixes tag] > Signed-off-by: Kurt Kanzenbach <kurt@xxxxxxxxxxxxx> Acked-by: Maciej Fijalkowski <maciej.fijalkowski@xxxxxxxxx> Thanks! > --- > drivers/net/ethernet/intel/igb/igb_main.c | 17 +++++++++++++---- > 1 file changed, 13 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c > index 33a42b4c21e0..c71eb2bbb23d 100644 > --- a/drivers/net/ethernet/intel/igb/igb_main.c > +++ b/drivers/net/ethernet/intel/igb/igb_main.c > @@ -33,6 +33,7 @@ > #include <linux/bpf_trace.h> > #include <linux/pm_runtime.h> > #include <linux/etherdevice.h> > +#include <linux/lockdep.h> > #ifdef CONFIG_IGB_DCA > #include <linux/dca.h> > #endif > @@ -2914,8 +2915,11 @@ static int igb_xdp(struct net_device *dev, struct netdev_bpf *xdp) > } > } > > +/* This function assumes __netif_tx_lock is held by the caller. */ > static void igb_xdp_ring_update_tail(struct igb_ring *ring) > { > + lockdep_assert_held(&txring_txq(ring)->_xmit_lock); > + > /* Force memory writes to complete before letting h/w know there > * are new descriptors to fetch. > */ > @@ -3000,11 +3004,11 @@ static int igb_xdp_xmit(struct net_device *dev, int n, > nxmit++; > } > > - __netif_tx_unlock(nq); > - > if (unlikely(flags & XDP_XMIT_FLUSH)) > igb_xdp_ring_update_tail(tx_ring); > > + __netif_tx_unlock(nq); > + > return nxmit; > } > > @@ -8854,12 +8858,14 @@ static void igb_put_rx_buffer(struct igb_ring *rx_ring, > > static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) > { > + unsigned int total_bytes = 0, total_packets = 0; > struct igb_adapter *adapter = q_vector->adapter; > struct igb_ring *rx_ring = q_vector->rx.ring; > - struct sk_buff *skb = rx_ring->skb; > - unsigned int total_bytes = 0, total_packets = 0; > u16 cleaned_count = igb_desc_unused(rx_ring); > + struct sk_buff *skb = rx_ring->skb; > + int cpu = smp_processor_id(); > unsigned int xdp_xmit = 0; > + struct netdev_queue *nq; > struct xdp_buff xdp; > u32 frame_sz = 0; > int rx_buf_pgcnt; > @@ -8987,7 +8993,10 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) > if (xdp_xmit & IGB_XDP_TX) { > struct igb_ring *tx_ring = igb_xdp_tx_queue_mapping(adapter); > > + nq = txring_txq(tx_ring); > + __netif_tx_lock(nq, cpu); > igb_xdp_ring_update_tail(tx_ring); > + __netif_tx_unlock(nq); > } > > u64_stats_update_begin(&rx_ring->rx_syncp); > > --- > base-commit: a0b4a80ed6ce2cf8140fe926303ba609884b5d9b > change-id: 20240822-igb_xdp_tx_lock-b6846fddc758 > > Best regards, > -- > Kurt Kanzenbach <kurt@xxxxxxxxxxxxx> >