On Saturday, December 20, 2025 7:00 PM, Vivek Behera wrote:
>This patch addresses the issue where the igc_xsk_wakeup function
>was triggering an incorrect IRQ for tx-0 when the i226 is configured
>with only 2 combined queues or in an environment with 2 active CPU cores.
>This prevented XDP Zero-copy send functionality in such split IRQ
>configurations.
>
>The fix implements the correct logic for extracting q_vectors saved
>during rx and tx ring allocation and utilizes flags provided by the
>ndo_xsk_wakeup API to trigger the appropriate IRQ.
>
>Fixes: fc9df2a0b520 ("igc: Enable RX via AF_XDP zero-copy")
>Fixes: 15fd021bc427 ("igc: Add Tx hardware timestamp request for AF_XDP zero-
>copy packet")
>Signed-off-by: Vivek Behera <[email protected]>
>Reviewed-by: Jacob Keller <[email protected]>
>Reviewed-by: Aleksandr loktinov <[email protected]>
>Reviewed-by: Piotr Kwapulinski <[email protected]>Reviewed-by: Song Yoong Siang <[email protected]> Thanks for the rework. Note: You do not need to submit a new version just to add a reviewed-by tag, unless you have another changes to make. >--- >v1: >https://lore.kernel.or/ >g%2Fintel-wired- >lan%2FAS1PR10MB5392B7268416DB8A1624FDB88FA7A%40AS1PR10MB5392.EUR >PRD10.PROD.OUTLOOK.COM%2F&data=05%7C02%7Cvivek.behera%40siemens.co >m%7Cb609a859d19b47e8f47808de38d77627%7C38ae3bcd95794fd4addab42e149 >5d55a%7C1%7C0%7C639010695226787962%7CUnknown%7CTWFpbGZsb3d8eyJF >bXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCI >sIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=S1060xzCOGrJo0cO2enNhDmCIJUcC >LZd%2F%2BmKLByazm8%3D&reserved=0 >v2: >https://lore.kernel.or/ >g%2Fintel-wired- >lan%2FAS1PR10MB539280B1427DA0ABE9D65E628FA5A%40AS1PR10MB5392.EUR >PRD10.PROD.OUTLOOK.COM%2F&data=05%7C02%7Cvivek.behera%40siemens.co >m%7Cb609a859d19b47e8f47808de38d77627%7C38ae3bcd95794fd4addab42e149 >5d55a%7C1%7C0%7C639010695226846016%7CUnknown%7CTWFpbGZsb3d8eyJF >bXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCI >sIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ksDVfndVlbafyexZ2%2B3j9GccO9hu >pybvtl1twZs5OSk%3D&reserved=0 >v3: >https://lore.kernel.or/ >g%2Fintel-wired- >lan%2FIA3PR11MB8986E4ACB7F264CF2DD1D750E5A0A%40IA3PR11MB8986.nam >prd11.prod.outlook.com%2F&data=05%7C02%7Cvivek.behera%40siemens.com%7C >b609a859d19b47e8f47808de38d77627%7C38ae3bcd95794fd4addab42e1495d55a >%7C1%7C0%7C639010695226890990%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0e >U1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIj >oyfQ%3D%3D%7C0%7C%7C%7C&sdata=zEWhj7N2%2BmwsShmoy1ACAjb3vi7yJgb >A077fISIOZiM%3D&reserved=0 >v4: >https://lore.kernel.or/ >g%2Fintel-wired- >lan%2FAS1PR10MB53926CB955FBD4F9F4A018818FA0A%40AS1PR10MB5392.EUR >PRD10.PROD.OUTLOOK.COM%2F&data=05%7C02%7Cvivek.behera%40siemens.co >m%7Cb609a859d19b47e8f47808de38d77627%7C38ae3bcd95794fd4addab42e149 >5d55a%7C1%7C0%7C639010695226933538%7CUnknown%7CTWFpbGZsb3d8eyJF >bXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCI >sIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=23aTM4TNsnyzoS%2FpSM1GcluaWz >LPNbrPKEo%2BOrm9hZQ%3D&reserved=0 >v5: >https://lore.kernel.or/ >g%2Fintel-wired- >lan%2FAS1PR10MB5392FCA415A38B9DD7BB5F218FA0A%40AS1PR10MB5392.EUR >PRD10.PROD.OUTLOOK.COM%2F&data=05%7C02%7Cvivek.behera%40siemens.co >m%7Cb609a859d19b47e8f47808de38d77627%7C38ae3bcd95794fd4addab42e149 >5d55a%7C1%7C0%7C639010695227205026%7CUnknown%7CTWFpbGZsb3d8eyJF >bXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCI >sIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=JdY3aHzIcIWtir9fAV%2BMELNWtiyLJ >YRU7IMxLZ0mPqQ%3D&reserved=0 >v6: https://lore.kernel.org/intel-wired-lan/20251211173916.23951-1- >[email protected]/ >v7: https://lore.kernel.org/intel-wired-lan/20251212163208.137164-1- >[email protected]/ >v8: https://lore.kernel.org/intel-wired-lan/20251215122052.412327-1- >[email protected]/ > >changelog: >v1 >- Inital description of the Bug and steps to reproduce with RTC Testbench >- Test results after applying the patch >v1 -> v2 >- Handling of RX and TX Wakeup in igc_xsk_wakeup for a split IRQ configuration >- Removal of igc_trigger_rxtxq_interrupt (now redundant) >- Added flag to igc_xsk_wakeup function call in igc_ptp_free_tx_buffer >v2 -> v3 >- Added 'Fixes:' tags for the relevant commits. >- Added reviewer >v3 -> v4 >- Added reviewer >v4 -> v5 >- Updated comment style from multi-star to standard linux convention >v5 -> v6 >- Resolve formatting issues highlighted by reviewers >- Try to include version histroy as defined in netdev guidelines >- Included review suggestions from Przemyslaw >- Added reviewers >v6 -> v7 >- Included review suggestions from Przemyslaw missed in v6 >v7 -> v8 >- Modified sequence to complete all error checks for rx and tx > before updating napi states and triggering irq >v8 -> v9 >- Included review feedback and suggestions from Tony and Siang >--- > drivers/net/ethernet/intel/igc/igc_main.c | 77 ++++++++++++++++++----- > drivers/net/ethernet/intel/igc/igc_ptp.c | 3 +- > 2 files changed, 62 insertions(+), 18 deletions(-) > >diff --git a/drivers/net/ethernet/intel/igc/igc_main.c >b/drivers/net/ethernet/intel/igc/igc_main.c >index 7aafa60ba0c8..7bd9f10a3f29 100644 >--- a/drivers/net/ethernet/intel/igc/igc_main.c >+++ b/drivers/net/ethernet/intel/igc/igc_main.c >@@ -6908,40 +6908,83 @@ static int igc_xdp_xmit(struct net_device *dev, int >num_frames, > return nxmit; > } > >-static void igc_trigger_rxtxq_interrupt(struct igc_adapter *adapter, >- struct igc_q_vector *q_vector) >-{ >- struct igc_hw *hw = &adapter->hw; >- u32 eics = 0; >- >- eics |= q_vector->eims_value; >- wr32(IGC_EICS, eics); >-} >- > int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags) > { > struct igc_adapter *adapter = netdev_priv(dev); >+ struct igc_hw *hw = &adapter->hw; > struct igc_q_vector *q_vector; > struct igc_ring *ring; >+ u32 eics = 0; > > if (test_bit(__IGC_DOWN, &adapter->state)) > return -ENETDOWN; > > if (!igc_xdp_is_enabled(adapter)) > return -ENXIO; >- >+ /* Check if queue_id is valid. Tx and Rx queue numbers are always same >*/ > if (queue_id >= adapter->num_rx_queues) > return -EINVAL; > >- ring = adapter->rx_ring[queue_id]; >- >+ if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) { >+ /* If both TX and RX need to be woken up check if queue pairs >are >active */ >+ if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS)) { >+ /* Just get the ring params from Rx */ >+ ring = adapter->rx_ring[queue_id]; >+ } else { >+ /* Two irqs for Rx and Tx need to be triggered */ >+ struct napi_struct *rx_napi; >+ struct napi_struct *tx_napi; >+ u32 eics_tx = 0; >+ u32 eics_rx = 0; >+ /* IRQ trigger preparation for Rx */ >+ ring = adapter->rx_ring[queue_id]; >+ if (!ring->xsk_pool) >+ return -ENXIO; >+ q_vector = ring->q_vector; >+ rx_napi = &q_vector->napi; >+ /* Extend the BIT mask for eics */ >+ eics_rx = ring->q_vector->eims_value; >+ >+ /* IRQ trigger preparation for Tx */ >+ ring = adapter->tx_ring[queue_id]; >+ if (!ring->xsk_pool) >+ return -ENXIO; >+ q_vector = ring->q_vector; >+ tx_napi = &q_vector->napi; >+ /* Extend the BIT mask for eics */ >+ eics_tx = ring->q_vector->eims_value; >+ >+ /* Check and update napi states for rx and tx */ >+ if (!napi_if_scheduled_mark_missed(rx_napi)) >+ eics |= eics_rx; >+ if (!napi_if_scheduled_mark_missed(tx_napi)) >+ eics |= eics_tx; >+ >+ /* Now we trigger the required irqs for Rx and Tx */ >+ if (eics) >+ wr32(IGC_EICS, eics); >+ >+ return 0; >+ } >+ } else if (flags & XDP_WAKEUP_TX) { >+ /* Get the ring params from Tx */ >+ ring = adapter->tx_ring[queue_id]; >+ } else if (flags & XDP_WAKEUP_RX) { >+ /* Get the ring params from Rx */ >+ ring = adapter->rx_ring[queue_id]; >+ } else { >+ /* Invalid Flags */ >+ return -EINVAL; >+ } >+ /* Prepare to trigger single irq */ > if (!ring->xsk_pool) > return -ENXIO; > >- q_vector = adapter->q_vector[queue_id]; >- if (!napi_if_scheduled_mark_missed(&q_vector->napi)) >- igc_trigger_rxtxq_interrupt(adapter, q_vector); >- >+ q_vector = ring->q_vector; >+ if (!napi_if_scheduled_mark_missed(&q_vector->napi)) { >+ eics = q_vector->eims_value; >+ wr32(IGC_EICS, eics); >+ } > return 0; > } > >diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c >b/drivers/net/ethernet/intel/igc/igc_ptp.c >index b7b46d863bee..df2e500a4d7e 100644 >--- a/drivers/net/ethernet/intel/igc/igc_ptp.c >+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c >@@ -550,7 +550,8 @@ static void igc_ptp_free_tx_buffer(struct igc_adapter >*adapter, > tstamp->buffer_type = 0; > > /* Trigger txrx interrupt for transmit completion */ >- igc_xsk_wakeup(adapter->netdev, tstamp->xsk_queue_index, 0); >+ igc_xsk_wakeup(adapter->netdev, tstamp->xsk_queue_index, >+ XDP_WAKEUP_TX); > > return; > }
