* [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
@ 2025-12-05 12:39 Behera, VIVEK
[not found] ` <IA3PR11MB8986860C6B817F4130A4E0DBE5A7A@IA3PR11MB8986.namprd11.prod.outlook.com>
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-05 12:39 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel, Andrew Lunn,
"David S. Miller", Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Behera, VIVEK
[-- Attachment #1.1: Type: text/plain, Size: 6556 bytes --]
From 4e3ebdc0af6baa83ccfc17c61c1eb61408095ffd Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
When the i226 is configured to use only 2 combined queues using ethtool
or in an environment with only 2 active CPU cores the 4 irq lines
are used in a split configuration with one irq
assigned to each of the two rx and tx queues
(see console output below)
sudo ethtool -l enp1s0
Channel parameters for enp1s0:
Pre-set maximums:
RX: n/a
TX: n/a
Other: 1
Combined: 4
Current hardware settings:
RX: n/a
TX: n/a
Other: 1
Combined: 2
eddx@mvs:~$ cat /proc/interrupts | grep enp1s0
147: 1 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
148: 8 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
149: 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
150: 26 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
151: 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
While testing with the RTC Testbench it was noticed
using the bpftrace that the
igc_xsk_wakeup when triggered by xsk_sendmsg
was triggering the incorrect irq for
tx-0(see trace below)
TIMESTAMP: 456992309829 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456992317157 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456993309408 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456993316591 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456994309630 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456994316674 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456995309493 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456995316593 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
Due to this bug no XDP Zc send is possible in this split irq configuration.
This patch implements the correct logic of extracting the q_vectors saved
duirng the rx and tx ring allocation.
Furthermore the patch includes usage of flags provided by the ndo_xsk_wakeup
api to trigger the required irq. With this patch correct irqs are triggered
cat /proc/interrupts | grep enp1s0
161: 1 0 0 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
162: 2 0 0 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
163: 359 0 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
164: 872005 0 0 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
165: 71 0 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
TIMESTAMP: 149658589239205 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
TIMESTAMP: 149658589244662 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589293396 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589295357 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 61
TIMESTAMP: 149658589342151 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589343881 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 3
TIMESTAMP: 149658589391394 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658590239215 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 31 +++++++++++++++++++----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..0cfcd20a2536 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6930,21 +6930,42 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
+ if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) {
+ /* If both TX and RX need to be woken up queue pair per IRQ is needed */
+ if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS))
+ return -EINVAL; /* igc queue pairs are not activated.
+ * Can't trigger irq
+ */
+ /* Just get the ring params from Rx */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* Get the ring params from Rx */
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /* Invalid Flags */
return -EINVAL;
-
- ring = adapter->rx_ring[queue_id];
+ }
if (!ring->xsk_pool)
return -ENXIO;
-
- q_vector = adapter->q_vector[queue_id];
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
if (!napi_if_scheduled_mark_missed(&q_vector->napi))
igc_trigger_rxtxq_interrupt(adapter, q_vector);
return 0;
}
+
static ktime_t igc_get_tstamp(struct net_device *dev,
const struct skb_shared_hwtstamps *hwtstamps,
bool cycles)
--
2.34.1
[-- Attachment #1.2: Type: text/html, Size: 28632 bytes --]
[-- Attachment #2: 0001-igc-Fix-trigger-of-incorrect-irq-in-igc_xsk_wakeup-f.patch --]
[-- Type: application/octet-stream, Size: 5711 bytes --]
From 4e3ebdc0af6baa83ccfc17c61c1eb61408095ffd Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
When the i226 is configured to use only 2 comined queues using ethtool
or in an environment with only 2 active CPU cores the 4 irq lines
are used in a split configuration with one irq
assigned to each of the two rx and tx queues
(see console output below)
sudo ethtool -l enp1s0
Channel parameters for enp1s0:
Pre-set maximums:
RX: n/a
TX: n/a
Other: 1
Combined: 4
Current hardware settings:
RX: n/a
TX: n/a
Other: 1
Combined: 2
eddx@mvs:~$ cat /proc/interrupts | grep enp1s0
147: 1 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
148: 8 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
149: 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
150: 26 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
151: 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
While testing with the RTC Testbench it was noticed
using the bpftrace that the
igc_xsk_wakeup when triggered by xsk_sendmsg
was triggering the incorrect irq for
tx-0(see trace below)
TIMESTAMP: 456992309829 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456992317157 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456993309408 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456993316591 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456994309630 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456994316674 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
TIMESTAMP: 456995309493 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
TIMESTAMP: 456995316593 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
Due to this bug no XDP Zc send is possible in this split irq configuration.
This patch implements the correct logic of extracting the q_vectors saved
duirng the rx and tx ring allocation.
Furthermore the patch includes usage of flags provided by the ndo_xsk_wakeup
api to trigger the required irq. With this patch correct irqs are triggered
cat /proc/interrupts | grep enp1s0
161: 1 0 0 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
162: 2 0 0 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
163: 359 0 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
164: 872005 0 0 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
165: 71 0 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
TIMESTAMP: 149658589239205 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
TIMESTAMP: 149658589244662 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589293396 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589295357 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 61
TIMESTAMP: 149658589342151 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658589343881 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 3
TIMESTAMP: 149658589391394 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
TIMESTAMP: 149658590239215 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 31 +++++++++++++++++++----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..0cfcd20a2536 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6930,21 +6930,42 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
+ if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) {
+ /* If both TX and RX need to be woken up queue pair per IRQ is needed */
+ if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS))
+ return -EINVAL; /* igc queue pairs are not activated.
+ * Can't trigger irq
+ */
+ /* Just get the ring params from Rx */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* Get the ring params from Rx */
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /* Invalid Flags */
return -EINVAL;
-
- ring = adapter->rx_ring[queue_id];
+ }
if (!ring->xsk_pool)
return -ENXIO;
-
- q_vector = adapter->q_vector[queue_id];
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
if (!napi_if_scheduled_mark_missed(&q_vector->napi))
igc_trigger_rxtxq_interrupt(adapter, q_vector);
return 0;
}
+
static ktime_t igc_get_tstamp(struct net_device *dev,
const struct skb_shared_hwtstamps *hwtstamps,
bool cycles)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
[not found] ` <IA3PR11MB8986860C6B817F4130A4E0DBE5A7A@IA3PR11MB8986.namprd11.prod.outlook.com>
@ 2025-12-06 12:03 ` Behera, VIVEK
0 siblings, 0 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-06 12:03 UTC (permalink / raw)
To: Loktionov, Aleksandr, Nguyen, Anthony L, Kitszel, Przemyslaw,
Andrew Lunn, "David S. Miller", Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Aleksandr ,
Thanks for the review and the valuable feedback!
On Fri, Dec 5, 2025 at 1:40 PM, Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> wrote:
> From 4e3ebdc0af6baa83ccfc17c61c1eb61408095ffd Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
>
> When the i226 is configured to use only 2 combined queues using ethtool
> or in an environment with only 2 active CPU cores the 4 irq lines
> are used in a split configuration with one irq
> assigned to each of the two rx and tx queues
> (see console output below)
>
>
> ...
>
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
> ---
> drivers/net/ethernet/intel/igc/igc_main.c | 31 +++++++++++++++++++----
> 1 file changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7aafa60ba0c8..0cfcd20a2536 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6930,21 +6930,42 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
>
> - if (queue_id >= adapter->num_rx_queues)
> + if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) {
> + /* If both TX and RX need to be woken up queue pair per IRQ is needed */
> + if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS))
> + return -EINVAL; /* igc queue pairs are not activated.
> + * Can't trigger irq
> + */
> It looks like not a malformed input, but as unsupported operation for the current device/IRQ configuration. In net drivers, -EOPNOTSUPP is the expected errno for "the device cannot perform this requested operation in this configuration," while -EINVAL signals a bad argument.
> Am I right?
When considering the split configuration, it would still be possible to trigger the individual IRQs for TX and RX. It is just about setting the correct bits in the EICS register. However, when I refer to the `ndo_xsk_wakeup` documentation, it isn't clear to me whether triggering multiple IRQs would be correct or desired. Referring to other netdev drivers implementing this hook, I couldn't find any instance of triggering individual IRQs in one call of the function. This could also be due to the fact that none of the drivers use the `flags` argument when the function is called. This is why I am inclined to handle this case as an error. You are right, the `-EOPNOTSUPP` would be the correct return value in this case. I will update this in the next version of the patch (v2) to reflect this change.
> + /* Just get the ring params from Rx */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + ring = adapter->rx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_TX) {
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL;
> + /* Get the ring params from Tx */
> + ring = adapter->tx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_RX) {
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + /* Get the ring params from Rx */
> + ring = adapter->rx_ring[queue_id];
> + } else {
> + /* Invalid Flags */
> return -EINVAL;
> ...
Thanks again for catching this!
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH v2] igc: Enhance xsk wakeup for split IRQ and fix PTP TX wakeup
2025-12-05 12:39 [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Behera, VIVEK
[not found] ` <IA3PR11MB8986860C6B817F4130A4E0DBE5A7A@IA3PR11MB8986.namprd11.prod.outlook.com>
@ 2025-12-07 15:46 ` Behera, VIVEK
2025-12-08 23:53 ` [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Jacob Keller
2 siblings, 0 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-07 15:46 UTC (permalink / raw)
To: Tony Nguyen, Przemek Kitszel, Andrew Lunn,
"David S. Miller", Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Behera, VIVEK
Hi everyone,
This is v2 of the patch "igc: Enhance xsk wakeup for split IRQ and fix PTP TX wakeup".
Changes in 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
Thanks,
Vivek Behera
From a9d7469510a21036e26a7804398d3e7a08c83b84 Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH v2] igc: Enhance xsk wakeup for split IRQ and fix PTP TX
wakeup
The igc_xsk_wakeup function previously returned an error when both
XDP_WAKEUP_RX and XDP_WAKEUP_TX flags were set but IGC_FLAG_QUEUE_PAIRS
was not active. This limitation prevented full XDP functionality in
configurations lacking queue pairs, such as specific i226 setups with
fewer active CPU cores or ethtool configurations.
Additionally, the igc_ptp_free_tx_buffer function was incorrectly
calling igc_xsk_wakeup with a zero 'flags' argument, which is an
invalid state and would lead to an -EINVAL return, preventing proper
TX completion wakeup.
This patch addresses these issues with the following changes:
1. **igc_xsk_wakeup Logic Enhancement:**
* The function now intelligently handles requests for both RX and TX
wakeups even when IGC_FLAG_QUEUE_PAIRS is not active. Instead of
returning an error, it prepares and triggers separate IRQs for the
RX and TX paths by accumulating the eims_value for both rings before
writing it once to eics.
* The static helper function 'igc_trigger_rxtxq_interrupt' has been
removed, and its functionality integrated directly into
igc_xsk_wakeup for a more unified and streamlined IRQ triggering
mechanism.
* Added explicit 'queue_id' validation for both 'num_rx_queues' and
'num_tx_queues' within the new split IRQ path to prevent potential
out-of-bounds access.
2. **PTP TX Wakeup Fix:**
* Corrected the call to igc_xsk_wakeup in igc_ptp_free_tx_buffer to
explicitly pass XDP_WAKEUP_TX as the 'flags' argument. This ensures
that the TX completion is properly signalled, resolving the previous
issue where 'flags=0' was passed, which would cause igc_xsk_wakeup
to return -EINVAL.
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++-----
drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
2 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..a130cdf4b45b 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6908,21 +6908,13 @@ 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;
@@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
- return -EINVAL;
+ 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 */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /***Two irqs for Rx AND Tx need to be triggered***/
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL; /**queue_id invalid**/
- ring = adapter->rx_ring[queue_id];
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL; /**queue_id invalid**/
- if (!ring->xsk_pool)
- return -ENXIO;
+ /**IRQ trigger preparation for Rx**/
+ ring = adapter->rx_ring[queue_id];
+ 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);
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value;
+ /**IRQ trigger preparation for Tx */
+ ring = adapter->tx_ring[queue_id];
+ if (!ring->xsk_pool)
+ return -ENXIO;
+
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value; /**Extend the BIT mask for eics**/
+
+ /***Now we trigger the split irqs for Rx and Tx over eics***/
+ if (eics != 0)
+ wr32(IGC_EICS, eics);
+
+ return 0;
+ }
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* 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;
+ /* Retrieve the q_vector saved in the ring */
+ 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..6d8c2d639cd7 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -550,7 +550,7 @@ 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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-05 12:39 [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Behera, VIVEK
[not found] ` <IA3PR11MB8986860C6B817F4130A4E0DBE5A7A@IA3PR11MB8986.namprd11.prod.outlook.com>
2025-12-07 15:46 ` [PATCH v2] igc: Enhance xsk wakeup for split IRQ and fix PTP TX wakeup Behera, VIVEK
@ 2025-12-08 23:53 ` Jacob Keller
2025-12-09 6:03 ` Behera, VIVEK
2 siblings, 1 reply; 14+ messages in thread
From: Jacob Keller @ 2025-12-08 23:53 UTC (permalink / raw)
To: Behera, VIVEK, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
[-- Attachment #1.1: Type: text/plain, Size: 7396 bytes --]
On 12/5/2025 4:39 AM, Behera, VIVEK wrote:
> From 4e3ebdc0af6baa83ccfc17c61c1eb61408095ffd Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
>
> When the i226 is configured to use only 2 combined queues using ethtool
> or in an environment with only 2 active CPU cores the 4 irq lines
> are used in a split configuration with one irq
> assigned to each of the two rx and tx queues
> (see console output below)
>
> sudo ethtool -l enp1s0
> Channel parameters for enp1s0:
> Pre-set maximums:
> RX: n/a
> TX: n/a
> Other: 1
> Combined: 4
> Current hardware settings:
> RX: n/a
> TX: n/a
> Other: 1
> Combined: 2
> eddx@mvs:~$ cat /proc/interrupts | grep enp1s0
> 147: 1 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
> 148: 8 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
> 149: 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
> 150: 26 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
> 151: 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
>
> While testing with the RTC Testbench it was noticed
> using the bpftrace that the
> igc_xsk_wakeup when triggered by xsk_sendmsg
> was triggering the incorrect irq for
> tx-0(see trace below)
>
> TIMESTAMP: 456992309829 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456992317157 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
> TIMESTAMP: 456993309408 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456993316591 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
> TIMESTAMP: 456994309630 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456994316674 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
> TIMESTAMP: 456995309493 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456995316593 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0- (PID: 948)
>
> Due to this bug no XDP Zc send is possible in this split irq configuration.
> This patch implements the correct logic of extracting the q_vectors saved
> duirng the rx and tx ring allocation.
> Furthermore the patch includes usage of flags provided by the ndo_xsk_wakeup
> api to trigger the required irq. With this patch correct irqs are triggered
>
> cat /proc/interrupts | grep enp1s0
> 161: 1 0 0 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
> 162: 2 0 0 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
> 163: 359 0 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
> 164: 872005 0 0 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
> 165: 71 0 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
>
> TIMESTAMP: 149658589239205 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
> TIMESTAMP: 149658589244662 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589293396 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589295357 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 61
> TIMESTAMP: 149658589342151 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589343881 | FUNCTION: xsk_tx_completed | ENTRY: irq/164-enp1s0- (PID: 10593) - num_entries: 3
> TIMESTAMP: 149658589391394 | FUNCTION: igc_poll | ENTRY: irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658590239215 | FUNCTION: igc_xsk_wakeup | ENTRY: RtcTxThread (PID: 10633) - queue_id: 0
>
I appreciate the detailed outline of how to configure the system so this
fails, and the steps taken to verify the change fixes the issue.
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
This is a bug fix, so it should be targeted at net. You will need a
Fixes tag associating which commit this fixes as well. Alternatively,
since this is for an Intel networking driver and you sent it to Intel
Wired LAN, it would be "iwl-net" so that it gets picked up by Tony for
testing along with our other igc changes.
> ---
> drivers/net/ethernet/intel/igc/igc_main.c | 31 +++++++++++++++++++----
> 1 file changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7aafa60ba0c8..0cfcd20a2536 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6930,21 +6930,42 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
> - if (queue_id >= adapter->num_rx_queues)
> + if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) {
> + /* If both TX and RX need to be woken up queue pair per IRQ is needed */
> + if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS))
> + return -EINVAL; /* igc queue pairs are not activated.
> + * Can't trigger irq
> + */
We only have to check for queue pairs if we want to wake both. Makes sense.
> + /* Just get the ring params from Rx */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + ring = adapter->rx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_TX) {
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL;
> + /* Get the ring params from Tx */
> + ring = adapter->tx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_RX) {
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + /* Get the ring params from Rx */
> + ring = adapter->rx_ring[queue_id];
> + } else {
> + /* Invalid Flags */
> return -EINVAL;
> -
> - ring = adapter->rx_ring[queue_id];
> + }
> if (!ring->xsk_pool)
> return -ENXIO;
> -
> - q_vector = adapter->q_vector[queue_id];
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> if (!napi_if_scheduled_mark_missed(&q_vector->napi))
> igc_trigger_rxtxq_interrupt(adapter, q_vector);
The actual code changes seem correct to me, so you may add my review tag
on a version which has the Fixes and the appropriate tree tag i.e.
[iwl-net] or [PATCH iwl-net].
Reviewed-by: Jacob Keller <jacob.keller@intel.com>
Thanks,
Jake
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-08 23:53 ` [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Jacob Keller
@ 2025-12-09 6:03 ` Behera, VIVEK
2025-12-09 6:46 ` [PATCH v3 iwl-net] " Behera, VIVEK
0 siblings, 1 reply; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-09 6:03 UTC (permalink / raw)
To: Jacob Keller, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Jacob,
Thank you very much for taking the time to review the patch and for the `Reviewed-by:` tag! I really appreciate your feedback.
Just wanted to let you know that I had already sent out `v2` of this patch, which included the PTP TX wakeup fix and addressed some `checkpatch.pl` comments.
For `v3`, I will incorporate your suggestions and send it out shortly.
Thanks again,
Vivek Behera
-----Original Message-----
From: Jacob Keller <jacob.e.keller@intel.com>
Sent: Tuesday, December 9, 2025 12:54 AM
To: Behera, Vivek (DI FA DSP ICC PRC1) <vivek.behera@siemens.com>; Tony Nguyen <anthony.l.nguyen@intel.com>; Przemek Kitszel <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>; David S. Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>
Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
On 12/5/2025 4:39 AM, Behera, VIVEK wrote:
> From 4e3ebdc0af6baa83ccfc17c61c1eb61408095ffd Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup
> function
>
> When the i226 is configured to use only 2 combined queues using
> ethtool or in an environment with only 2 active CPU cores the 4 irq
> lines are used in a split configuration with one irq assigned to each
> of the two rx and tx queues (see console output below)
>
> sudo ethtool -l enp1s0
> Channel parameters for enp1s0:
> Pre-set maximums:
> RX: n/a
> TX: n/a
> Other: 1
> Combined: 4
> Current hardware settings:
> RX: n/a
> TX: n/a
> Other: 1
> Combined: 2
> eddx@mvs:~$ cat /proc/interrupts | grep enp1s0
> 147: 1 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
> 148: 8 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
> 149: 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
> 150: 26 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
> 151: 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
>
> While testing with the RTC Testbench it was noticed using the bpftrace
> that the igc_xsk_wakeup when triggered by xsk_sendmsg was triggering
> the incorrect irq for tx-0(see trace below)
>
> TIMESTAMP: 456992309829 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456992317157 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0-
> (PID: 948)
> TIMESTAMP: 456993309408 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456993316591 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0-
> (PID: 948)
> TIMESTAMP: 456994309630 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456994316674 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0-
> (PID: 948)
> TIMESTAMP: 456995309493 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 945) - queue_id: 0
> TIMESTAMP: 456995316593 | FUNCTION: igc_poll | ENTRY: irq/148-enp1s0-
> (PID: 948)
>
> Due to this bug no XDP Zc send is possible in this split irq configuration.
> This patch implements the correct logic of extracting the q_vectors
> saved duirng the rx and tx ring allocation.
> Furthermore the patch includes usage of flags provided by the
> ndo_xsk_wakeup api to trigger the required irq. With this patch
> correct irqs are triggered
>
> cat /proc/interrupts | grep enp1s0
> 161: 1 0 0 0 IR-PCI-MSIX-0000:01:00.0 0-edge enp1s0
> 162: 2 0 0 0 IR-PCI-MSIX-0000:01:00.0 1-edge enp1s0-rx-0
> 163: 359 0 0 0 IR-PCI-MSIX-0000:01:00.0 2-edge enp1s0-rx-1
> 164: 872005 0 0 0 IR-PCI-MSIX-0000:01:00.0 3-edge enp1s0-tx-0
> 165: 71 0 0 0 IR-PCI-MSIX-0000:01:00.0 4-edge enp1s0-tx-1
>
> TIMESTAMP: 149658589239205 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 10633) - queue_id: 0
> TIMESTAMP: 149658589244662 | FUNCTION: igc_poll | ENTRY:
> irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589293396 | FUNCTION: igc_poll | ENTRY:
> irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589295357 | FUNCTION: xsk_tx_completed | ENTRY:
> irq/164-enp1s0- (PID: 10593) - num_entries: 61
> TIMESTAMP: 149658589342151 | FUNCTION: igc_poll | ENTRY:
> irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658589343881 | FUNCTION: xsk_tx_completed | ENTRY:
> irq/164-enp1s0- (PID: 10593) - num_entries: 3
> TIMESTAMP: 149658589391394 | FUNCTION: igc_poll | ENTRY:
> irq/164-enp1s0- (PID: 10593)
> TIMESTAMP: 149658590239215 | FUNCTION: igc_xsk_wakeup | ENTRY:
> RtcTxThread (PID: 10633) - queue_id: 0
>
I appreciate the detailed outline of how to configure the system so this fails, and the steps taken to verify the change fixes the issue.
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
This is a bug fix, so it should be targeted at net. You will need a Fixes tag associating which commit this fixes as well. Alternatively, since this is for an Intel networking driver and you sent it to Intel Wired LAN, it would be "iwl-net" so that it gets picked up by Tony for testing along with our other igc changes.
> ---
> drivers/net/ethernet/intel/igc/igc_main.c | 31 +++++++++++++++++++----
> 1 file changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
> b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7aafa60ba0c8..0cfcd20a2536 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6930,21 +6930,42 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
> - if (queue_id >= adapter->num_rx_queues)
> + if ((flags & XDP_WAKEUP_RX) && (flags & XDP_WAKEUP_TX)) {
> + /* If both TX and RX need to be woken up queue pair per IRQ is needed */
> + if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS))
> + return -EINVAL; /* igc queue pairs are not activated.
> + * Can't trigger irq
> + */
We only have to check for queue pairs if we want to wake both. Makes sense.
> + /* Just get the ring params from Rx */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + ring = adapter->rx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_TX) {
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL;
> + /* Get the ring params from Tx */
> + ring = adapter->tx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_RX) {
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + /* Get the ring params from Rx */
> + ring = adapter->rx_ring[queue_id];
> + } else {
> + /* Invalid Flags */
> return -EINVAL;
> -
> - ring = adapter->rx_ring[queue_id];
> + }
> if (!ring->xsk_pool)
> return -ENXIO;
> -
> - q_vector = adapter->q_vector[queue_id];
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> if (!napi_if_scheduled_mark_missed(&q_vector->napi))
> igc_trigger_rxtxq_interrupt(adapter, q_vector);
The actual code changes seem correct to me, so you may add my review tag on a version which has the Fixes and the appropriate tree tag i.e.
[iwl-net] or [PATCH iwl-net].
Reviewed-by: Jacob Keller <jacob.keller@intel.com>
Thanks,
Jake
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-09 6:03 ` Behera, VIVEK
@ 2025-12-09 6:46 ` Behera, VIVEK
2025-12-09 8:05 ` Loktionov, Aleksandr
2025-12-10 10:15 ` [PATCH v3 " Kwapulinski, Piotr
0 siblings, 2 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-09 6:46 UTC (permalink / raw)
To: Behera, VIVEK, Jacob Keller, Tony Nguyen, Przemek Kitszel,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Changes in v3:
- Added 'Fixes:' tags for the relevant commits.
- Added 'Reviewed-by:' tag from Jacob Keller.
- Updated subject line with '[iwl-net]' prefix.
From 32422588358a537ef79de4ff630e4414e2c6b934 Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in
igc_xsk_wakeup function
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: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
Reviewed-by: Jacob Keller <jacob.keller@intel.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++-----
drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
2 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..a130cdf4b45b 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6908,21 +6908,13 @@ 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;
@@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
- return -EINVAL;
+ 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 */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /***Two irqs for Rx AND Tx need to be triggered***/
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL; /**queue_id invalid**/
- ring = adapter->rx_ring[queue_id];
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL; /**queue_id invalid**/
- if (!ring->xsk_pool)
- return -ENXIO;
+ /**IRQ trigger preparation for Rx**/
+ ring = adapter->rx_ring[queue_id];
+ 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);
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value;
+ /**IRQ trigger preparation for Tx */
+ ring = adapter->tx_ring[queue_id];
+ if (!ring->xsk_pool)
+ return -ENXIO;
+
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value; /**Extend the BIT mask for eics**/
+
+ /***Now we trigger the split irqs for Rx and Tx over eics***/
+ if (eics != 0)
+ wr32(IGC_EICS, eics);
+
+ return 0;
+ }
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* 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;
+ /* Retrieve the q_vector saved in the ring */
+ 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..6d8c2d639cd7 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -550,7 +550,7 @@ 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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-09 6:46 ` [PATCH v3 iwl-net] " Behera, VIVEK
@ 2025-12-09 8:05 ` Loktionov, Aleksandr
2025-12-10 7:09 ` AW: [PATCH v4 " Behera, VIVEK
2025-12-10 7:16 ` [PATCH v3 " Loktionov, Aleksandr
2025-12-10 10:15 ` [PATCH v3 " Kwapulinski, Piotr
1 sibling, 2 replies; 14+ messages in thread
From: Loktionov, Aleksandr @ 2025-12-09 8:05 UTC (permalink / raw)
To: Behera, Vivek, Behera, Vivek, Keller, Jacob E, Nguyen, Anthony L,
Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Behera, VIVEK
> Sent: Tuesday, December 9, 2025 7:47 AM
> To: Behera, Vivek <vivek.behera@siemens.com>; Keller, Jacob E
> <jacob.e.keller@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> David S. Miller <davem@davemloft.net>; Eric Dumazet
> <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> <pabeni@redhat.com>
> Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 iwl-net] igc: Fix trigger of
> incorrect irq in igc_xsk_wakeup function
>
> Changes in v3:
> - Added 'Fixes:' tags for the relevant commits.
> - Added 'Reviewed-by:' tag from Jacob Keller.
> - Updated subject line with '[iwl-net]' prefix.
>
> From 32422588358a537ef79de4ff630e4414e2c6b934 Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in
> igc_xsk_wakeup function
>
> 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: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via
> AF_XDP zero-copy")
> Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware
> timestamp request for AF_XDP zero-copy packet")
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
> Reviewed-by: Jacob Keller <jacob.keller@intel.com>
> ---
> drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++----
> - drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
> 2 files changed, 64 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
> b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7aafa60ba0c8..a130cdf4b45b 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6908,21 +6908,13 @@ 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;
> @@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32
> queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
>
> - if (queue_id >= adapter->num_rx_queues)
> - return -EINVAL;
> + 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 */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + ring = adapter->rx_ring[queue_id];
> + } else {
> + /***Two irqs for Rx AND Tx need to be
> triggered***/
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL; /**queue_id invalid**/
>
> - ring = adapter->rx_ring[queue_id];
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL; /**queue_id invalid**/
>
> - if (!ring->xsk_pool)
> - return -ENXIO;
> + /**IRQ trigger preparation for Rx**/
> + ring = adapter->rx_ring[queue_id];
> + 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);
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> + if (!napi_if_scheduled_mark_missed(&q_vector-
> >napi))
> + eics |= q_vector->eims_value;
> + /**IRQ trigger preparation for Tx */
> + ring = adapter->tx_ring[queue_id];
>
> + if (!ring->xsk_pool)
> + return -ENXIO;
> +
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> + if (!napi_if_scheduled_mark_missed(&q_vector-
> >napi))
> + eics |= q_vector->eims_value; /**Extend the
> BIT mask for eics**/
> +
> + /***Now we trigger the split irqs for Rx and Tx
> over eics***/
> + if (eics != 0)
> + wr32(IGC_EICS, eics);
> +
> + return 0;
> + }
> + } else if (flags & XDP_WAKEUP_TX) {
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL;
> + /* Get the ring params from Tx */
> + ring = adapter->tx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_RX) {
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + /* 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;
> + /* Retrieve the q_vector saved in the ring */
> + 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..6d8c2d639cd7 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ptp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
> @@ -550,7 +550,7 @@ 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;
> }
> --
> 2.34.1
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* AW: [PATCH v4 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-09 8:05 ` Loktionov, Aleksandr
@ 2025-12-10 7:09 ` Behera, VIVEK
2025-12-10 7:16 ` [PATCH v3 " Loktionov, Aleksandr
1 sibling, 0 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-10 7:09 UTC (permalink / raw)
To: Loktionov, Aleksandr, Keller, Jacob E, Nguyen, Anthony L,
Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Changes in v4
- Added 'Reviewed-by:' tag from: Aleksandr loktionov .
From 2cb8e6a8d3c7bf1be51e803dabf91e2b80b3a4e2 Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH v4 iwl-net] igc: Fix trigger of incorrect irq in
igc_xsk_wakeup function
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: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
Reviewed-by: Jacob Keller <jacob.keller@intel.com>
Reviewed-by: Aleksandr loktionov <aleksandr.loktionov@intel.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++-----
drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
2 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..a130cdf4b45b 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6908,21 +6908,13 @@ 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;
@@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
- return -EINVAL;
+ 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 */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /***Two irqs for Rx AND Tx need to be triggered***/
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL; /**queue_id invalid**/
- ring = adapter->rx_ring[queue_id];
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL; /**queue_id invalid**/
- if (!ring->xsk_pool)
- return -ENXIO;
+ /**IRQ trigger preparation for Rx**/
+ ring = adapter->rx_ring[queue_id];
+ 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);
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value;
+ /**IRQ trigger preparation for Tx */
+ ring = adapter->tx_ring[queue_id];
+ if (!ring->xsk_pool)
+ return -ENXIO;
+
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value; /**Extend the BIT mask for eics**/
+
+ /***Now we trigger the split irqs for Rx and Tx over eics***/
+ if (eics != 0)
+ wr32(IGC_EICS, eics);
+
+ return 0;
+ }
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* 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;
+ /* Retrieve the q_vector saved in the ring */
+ 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..6d8c2d639cd7 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -550,7 +550,7 @@ 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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-09 8:05 ` Loktionov, Aleksandr
2025-12-10 7:09 ` AW: [PATCH v4 " Behera, VIVEK
@ 2025-12-10 7:16 ` Loktionov, Aleksandr
2025-12-10 7:50 ` AW: [PATCH v5 " Behera, VIVEK
1 sibling, 1 reply; 14+ messages in thread
From: Loktionov, Aleksandr @ 2025-12-10 7:16 UTC (permalink / raw)
To: Loktionov, Aleksandr, Behera, Vivek, Behera, Vivek,
Keller, Jacob E, Nguyen, Anthony L, Kitszel, Przemyslaw,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Loktionov, Aleksandr
> Sent: Tuesday, December 9, 2025 9:06 AM
> To: Behera, Vivek <vivek.behera@siemens.com>; Behera, Vivek
> <vivek.behera@siemens.com>; Keller, Jacob E
> <jacob.e.keller@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> David S. Miller <davem@davemloft.net>; Eric Dumazet
> <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> <pabeni@redhat.com>
> Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: Re: [Intel-wired-lan] [PATCH v3 iwl-net] igc: Fix trigger of
> incorrect irq in igc_xsk_wakeup function
>
>
>
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Behera, VIVEK
> > Sent: Tuesday, December 9, 2025 7:47 AM
> > To: Behera, Vivek <vivek.behera@siemens.com>; Keller, Jacob E
> > <jacob.e.keller@intel.com>; Nguyen, Anthony L
> > <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> > <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> > David S. Miller <davem@davemloft.net>; Eric Dumazet
> > <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> > <pabeni@redhat.com>
> > Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> > kernel@vger.kernel.org
> > Subject: [Intel-wired-lan] [PATCH v3 iwl-net] igc: Fix trigger of
> > incorrect irq in igc_xsk_wakeup function
> >
> > Changes in v3:
> > - Added 'Fixes:' tags for the relevant commits.
> > - Added 'Reviewed-by:' tag from Jacob Keller.
> > - Updated subject line with '[iwl-net]' prefix.
> >
> > From 32422588358a537ef79de4ff630e4414e2c6b934 Mon Sep 17 00:00:00
> 2001
> > From: Vivek Behera <vivek.behera@siemens.com>
> > Date: Fri, 5 Dec 2025 10:26:05 +0100
> > Subject: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in
> > igc_xsk_wakeup function
> >
> > 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: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via
> > AF_XDP zero-copy")
> > Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx
> hardware
> > timestamp request for AF_XDP zero-copy packet")
> > Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
> > Reviewed-by: Jacob Keller <jacob.keller@intel.com>
> > ---
> > drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++--
> --
> > - drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
> > 2 files changed, 64 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/intel/igc/igc_main.c
> > b/drivers/net/ethernet/intel/igc/igc_main.c
> > index 7aafa60ba0c8..a130cdf4b45b 100644
> > --- a/drivers/net/ethernet/intel/igc/igc_main.c
> > +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> > @@ -6908,21 +6908,13 @@ 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;
> > @@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev,
> u32
> > queue_id, u32 flags)
> > if (!igc_xdp_is_enabled(adapter))
> > return -ENXIO;
> >
> > - if (queue_id >= adapter->num_rx_queues)
> > - return -EINVAL;
> > + 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 */
> > + if (queue_id >= adapter->num_rx_queues)
> > + return -EINVAL;
> > + ring = adapter->rx_ring[queue_id];
> > + } else {
> > + /***Two irqs for Rx AND Tx need to be
> > triggered***/
> > + if (queue_id >= adapter->num_rx_queues)
> > + return -EINVAL; /**queue_id invalid**/
> >
> > - ring = adapter->rx_ring[queue_id];
> > + if (queue_id >= adapter->num_tx_queues)
> > + return -EINVAL; /**queue_id invalid**/
> >
> > - if (!ring->xsk_pool)
> > - return -ENXIO;
> > + /**IRQ trigger preparation for Rx**/
> > + ring = adapter->rx_ring[queue_id];
> > + 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);
> > + /* Retrieve the q_vector saved in the ring */
> > + q_vector = ring->q_vector;
> > + if (!napi_if_scheduled_mark_missed(&q_vector-
> > >napi))
> > + eics |= q_vector->eims_value;
> > + /**IRQ trigger preparation for Tx */
> > + ring = adapter->tx_ring[queue_id];
> >
> > + if (!ring->xsk_pool)
> > + return -ENXIO;
> > +
> > + /* Retrieve the q_vector saved in the ring */
> > + q_vector = ring->q_vector;
> > + if (!napi_if_scheduled_mark_missed(&q_vector-
> > >napi))
> > + eics |= q_vector->eims_value; /**Extend the
> > BIT mask for eics**/
> > +
> > + /***Now we trigger the split irqs for Rx and Tx
> > over eics***/
Just a nit, I think it could be nice if you change multi-star to standard linux comments /* */
With the best regards
Alex
> > --
> > 2.34.1
>
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* AW: [PATCH v5 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-10 7:16 ` [PATCH v3 " Loktionov, Aleksandr
@ 2025-12-10 7:50 ` Behera, VIVEK
2025-12-10 8:57 ` Jakub Kicinski
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Behera, VIVEK @ 2025-12-10 7:50 UTC (permalink / raw)
To: Loktionov, Aleksandr, Keller, Jacob E, Nguyen, Anthony L,
Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Changes in v5:
- Updated comment style from multi-star to standard /* */ as suggested by Aleksandr.
From ab2583ff8a17405d3aa6caf4df1c4fdfb21f5e98 Mon Sep 17 00:00:00 2001
From: Vivek Behera <vivek.behera@siemens.com>
Date: Fri, 5 Dec 2025 10:26:05 +0100
Subject: [PATCH v5] [iwl-net] igc: Fix trigger of incorrect irq in
igc_xsk_wakeup function
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.
Changed comment blocks to align with standard Linux comments
Fixes: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
Reviewed-by: Jacob Keller <jacob.keller@intel.com>
Reviewed-by: Aleksandr loktinov <aleksandr.loktionov@intel.com>
---
drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++-----
drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
2 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 7aafa60ba0c8..c7bf5a4b89e9 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -6908,21 +6908,13 @@ 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;
@@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
if (!igc_xdp_is_enabled(adapter))
return -ENXIO;
- if (queue_id >= adapter->num_rx_queues)
- return -EINVAL;
+ 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 */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ ring = adapter->rx_ring[queue_id];
+ } else {
+ /* Two irqs for Rx AND Tx need to be triggered */
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL; /*queue_id is invalid*/
- ring = adapter->rx_ring[queue_id];
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL; /* queue_id invalid */
- if (!ring->xsk_pool)
- return -ENXIO;
+ /* IRQ trigger preparation for Rx */
+ ring = adapter->rx_ring[queue_id];
+ 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);
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value;
+ /* IRQ trigger preparation for Tx */
+ ring = adapter->tx_ring[queue_id];
+ if (!ring->xsk_pool)
+ return -ENXIO;
+
+ /* Retrieve the q_vector saved in the ring */
+ q_vector = ring->q_vector;
+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
+ eics |= q_vector->eims_value; /* Extend the BIT mask for eics */
+
+ /* Now we trigger the split irqs for Rx and Tx over eics */
+ if (eics != 0)
+ wr32(IGC_EICS, eics);
+
+ return 0;
+ }
+ } else if (flags & XDP_WAKEUP_TX) {
+ if (queue_id >= adapter->num_tx_queues)
+ return -EINVAL;
+ /* Get the ring params from Tx */
+ ring = adapter->tx_ring[queue_id];
+ } else if (flags & XDP_WAKEUP_RX) {
+ if (queue_id >= adapter->num_rx_queues)
+ return -EINVAL;
+ /* 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;
+ /* Retrieve the q_vector saved in the ring */
+ 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..6d8c2d639cd7 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -550,7 +550,7 @@ 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;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v5 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-10 7:50 ` AW: [PATCH v5 " Behera, VIVEK
@ 2025-12-10 8:57 ` Jakub Kicinski
2025-12-10 10:16 ` AW: " Kurt Kanzenbach
2025-12-10 16:41 ` [Intel-wired-lan] " Paul Menzel
2 siblings, 0 replies; 14+ messages in thread
From: Jakub Kicinski @ 2025-12-10 8:57 UTC (permalink / raw)
To: Behera, VIVEK
Cc: Loktionov, Aleksandr, Keller, Jacob E, Nguyen, Anthony L,
Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
Paolo Abeni, intel-wired-lan@lists.osuosl.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
On Wed, 10 Dec 2025 07:50:55 +0000 Behera, VIVEK wrote:
> Changes in v5:
> - Updated comment style from multi-star to standard /* */ as suggested by Aleksandr.
>
> From ab2583ff8a17405d3aa6caf4df1c4fdfb21f5e98 Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH v5] [iwl-net] igc: Fix trigger of incorrect irq in
> igc_xsk_wakeup function
The formatting of your submissions is all wrong. And you don't follow
our guidance:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html
Perhaps drop netdev@ and linux-kernel@ from the CC and Intel folks can
help guide/teach you on their own list. Until you have the posting
down..
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-09 6:46 ` [PATCH v3 iwl-net] " Behera, VIVEK
2025-12-09 8:05 ` Loktionov, Aleksandr
@ 2025-12-10 10:15 ` Kwapulinski, Piotr
1 sibling, 0 replies; 14+ messages in thread
From: Kwapulinski, Piotr @ 2025-12-10 10:15 UTC (permalink / raw)
To: Behera, Vivek, Behera, Vivek, Keller, Jacob E, Nguyen, Anthony L,
Kitszel, Przemyslaw, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
>-----Original Message-----
>From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Behera, VIVEK
>Sent: Tuesday, December 9, 2025 7:47 AM
>To: Behera, Vivek <vivek.behera@siemens.com>; Keller, Jacob E <jacob.e.keller@intel.com>; Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>; David S. Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>
>Cc: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
>Subject: [Intel-wired-lan] [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
>
>Changes in v3:
>- Added 'Fixes:' tags for the relevant commits.
>- Added 'Reviewed-by:' tag from Jacob Keller.
>- Updated subject line with '[iwl-net]' prefix.
>
>From 32422588358a537ef79de4ff630e4414e2c6b934 Mon Sep 17 00:00:00 2001
>From: Vivek Behera <vivek.behera@siemens.com>
>Date: Fri, 5 Dec 2025 10:26:05 +0100
>Subject: [PATCH v3 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
>
>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: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
>Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
>Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
>Reviewed-by: Jacob Keller <jacob.keller@intel.com>
>---
> drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++----- drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
> 2 files changed, 64 insertions(+), 19 deletions(-)
>
>diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
>index 7aafa60ba0c8..a130cdf4b45b 100644
>--- a/drivers/net/ethernet/intel/igc/igc_main.c
>+++ b/drivers/net/ethernet/intel/igc/igc_main.c
>@@ -6908,21 +6908,13 @@ 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;
>@@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
>
>- if (queue_id >= adapter->num_rx_queues)
>- return -EINVAL;
>+ 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 */
>+ if (queue_id >= adapter->num_rx_queues)
>+ return -EINVAL;
>+ ring = adapter->rx_ring[queue_id];
>+ } else {
>+ /***Two irqs for Rx AND Tx need to be triggered***/
>+ if (queue_id >= adapter->num_rx_queues)
>+ return -EINVAL; /**queue_id invalid**/
Please consider this and the following (ditto) comments as redundant
>
>- ring = adapter->rx_ring[queue_id];
>+ if (queue_id >= adapter->num_tx_queues)
>+ return -EINVAL; /**queue_id invalid**/
Ditto
>
>- if (!ring->xsk_pool)
>- return -ENXIO;
>+ /**IRQ trigger preparation for Rx**/
>+ ring = adapter->rx_ring[queue_id];
>+ 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);
>+ /* Retrieve the q_vector saved in the ring */
Ditto
>+ q_vector = ring->q_vector;
>+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
>+ eics |= q_vector->eims_value;
>+ /**IRQ trigger preparation for Tx */
>+ ring = adapter->tx_ring[queue_id];
>
>+ if (!ring->xsk_pool)
>+ return -ENXIO;
>+
>+ /* Retrieve the q_vector saved in the ring */
Ditto
>+ q_vector = ring->q_vector;
>+ if (!napi_if_scheduled_mark_missed(&q_vector->napi))
>+ eics |= q_vector->eims_value; /**Extend the BIT mask for eics**/
>+
>+ /***Now we trigger the split irqs for Rx and Tx over eics***/
>+ if (eics != 0)
Please remove "!= 0".
Thank you.
Piotr
>+ wr32(IGC_EICS, eics);
>+
>+ return 0;
>+ }
>+ } else if (flags & XDP_WAKEUP_TX) {
>+ if (queue_id >= adapter->num_tx_queues)
>+ return -EINVAL;
>+ /* Get the ring params from Tx */
>+ ring = adapter->tx_ring[queue_id];
>+ } else if (flags & XDP_WAKEUP_RX) {
>+ if (queue_id >= adapter->num_rx_queues)
>+ return -EINVAL;
>+ /* 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;
>+ /* Retrieve the q_vector saved in the ring */
>+ 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..6d8c2d639cd7 100644
>--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
>+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
>@@ -550,7 +550,7 @@ 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;
> }
>--
>2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: AW: [PATCH v5 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-10 7:50 ` AW: [PATCH v5 " Behera, VIVEK
2025-12-10 8:57 ` Jakub Kicinski
@ 2025-12-10 10:16 ` Kurt Kanzenbach
2025-12-10 16:41 ` [Intel-wired-lan] " Paul Menzel
2 siblings, 0 replies; 14+ messages in thread
From: Kurt Kanzenbach @ 2025-12-10 10:16 UTC (permalink / raw)
To: Behera, VIVEK, Loktionov, Aleksandr, Keller, Jacob E,
Nguyen, Anthony L, Kitszel, Przemyslaw, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 1565 bytes --]
On Wed Dec 10 2025, Behera, VIVEK wrote:
> Changes in v5:
> - Updated comment style from multi-star to standard /* */ as suggested by Aleksandr.
>
> From ab2583ff8a17405d3aa6caf4df1c4fdfb21f5e98 Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH v5] [iwl-net] igc: Fix trigger of incorrect irq in
> igc_xsk_wakeup function
>
> 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.
>
> Changed comment blocks to align with standard Linux comments
>
> Fixes: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
> Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
> Reviewed-by: Jacob Keller <jacob.keller@intel.com>
> Reviewed-by: Aleksandr loktinov <aleksandr.loktionov@intel.com>
Hi,
thanks for this fix. Does the same issue also exist for i210 in the igb
driver? The igb driver also has this split IRQ configuration with 2
queues. Might be good to fix this one as well :).
Thanks,
Kurt
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Intel-wired-lan] [PATCH v5 iwl-net] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function
2025-12-10 7:50 ` AW: [PATCH v5 " Behera, VIVEK
2025-12-10 8:57 ` Jakub Kicinski
2025-12-10 10:16 ` AW: " Kurt Kanzenbach
@ 2025-12-10 16:41 ` Paul Menzel
2 siblings, 0 replies; 14+ messages in thread
From: Paul Menzel @ 2025-12-10 16:41 UTC (permalink / raw)
To: Vivek Behera
Cc: Aleksandr Loktionov, Jacob E Keller, Anthony L Nguyen,
Przemyslaw Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, intel-wired-lan, netdev,
linux-kernel
Dear Vivek,
Thank you for your patch.
Am 10.12.25 um 08:50 schrieb Behera, VIVEK:
What is your given name? ;-) I think in French, it’s common to
capitalize the surname.
> Changes in v5:
> - Updated comment style from multi-star to standard /* */ as
> suggested by Aleksandr.
It’s common to add that below the --- and above the diffstat.
> From ab2583ff8a17405d3aa6caf4df1c4fdfb21f5e98 Mon Sep 17 00:00:00 2001
> From: Vivek Behera <vivek.behera@siemens.com>
> Date: Fri, 5 Dec 2025 10:26:05 +0100
> Subject: [PATCH v5] [iwl-net] igc: Fix trigger of incorrect irq in
> igc_xsk_wakeup function
>
> 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.
>
> Changed comment blocks to align with standard Linux comments
Maybe “Also, change the comment blocks to …” and a dot/period at the end.
Do you have a reproducer for this? If yes, it’d be great if you
documented this in the commit message.
>
> Fixes: fc9df2a0b520d7d439ecf464794d53e91be74b93 ("igc: Enable RX via AF_XDP zero-copy")
It’s common to use 14(?) characters of the hash.
> Fixes: 15fd021bc4270273d8f4b7f58fdda8a16214a377 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet")
Ditto.
> Signed-off-by: Vivek Behera <vivek.behera@siemens.com>
> Reviewed-by: Jacob Keller <jacob.keller@intel.com>
> Reviewed-by: Aleksandr loktinov <aleksandr.loktionov@intel.com>
Please capitalize the last name.
> ---
> drivers/net/ethernet/intel/igc/igc_main.c | 81 ++++++++++++++++++-----
> drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +-
> 2 files changed, 64 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7aafa60ba0c8..c7bf5a4b89e9 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6908,21 +6908,13 @@ 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;
> @@ -6930,18 +6922,71 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
> if (!igc_xdp_is_enabled(adapter))
> return -ENXIO;
>
> - if (queue_id >= adapter->num_rx_queues)
> - return -EINVAL;
> + 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 */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + ring = adapter->rx_ring[queue_id];
> + } else {
> + /* Two irqs for Rx AND Tx need to be triggered */
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL; /*queue_id is invalid*/
>
> - ring = adapter->rx_ring[queue_id];
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL; /* queue_id invalid */
>
> - if (!ring->xsk_pool)
> - return -ENXIO;
> + /* IRQ trigger preparation for Rx */
> + ring = adapter->rx_ring[queue_id];
> + 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);
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> + if (!napi_if_scheduled_mark_missed(&q_vector->napi))
> + eics |= q_vector->eims_value;
> + /* IRQ trigger preparation for Tx */
> + ring = adapter->tx_ring[queue_id];
>
> + if (!ring->xsk_pool)
> + return -ENXIO;
> +
> + /* Retrieve the q_vector saved in the ring */
> + q_vector = ring->q_vector;
> + if (!napi_if_scheduled_mark_missed(&q_vector->napi))
> + eics |= q_vector->eims_value; /* Extend the BIT mask for eics */
> +
> + /* Now we trigger the split irqs for Rx and Tx over eics */
> + if (eics != 0)
> + wr32(IGC_EICS, eics);
> +
> + return 0;
> + }
> + } else if (flags & XDP_WAKEUP_TX) {
> + if (queue_id >= adapter->num_tx_queues)
> + return -EINVAL;
> + /* Get the ring params from Tx */
> + ring = adapter->tx_ring[queue_id];
> + } else if (flags & XDP_WAKEUP_RX) {
> + if (queue_id >= adapter->num_rx_queues)
> + return -EINVAL;
> + /* 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;
> + /* Retrieve the q_vector saved in the ring */
> + 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..6d8c2d639cd7 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ptp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
> @@ -550,7 +550,7 @@ 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;
> }
Kind regards,
Paul
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-12-10 16:42 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-05 12:39 [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Behera, VIVEK
[not found] ` <IA3PR11MB8986860C6B817F4130A4E0DBE5A7A@IA3PR11MB8986.namprd11.prod.outlook.com>
2025-12-06 12:03 ` Behera, VIVEK
2025-12-07 15:46 ` [PATCH v2] igc: Enhance xsk wakeup for split IRQ and fix PTP TX wakeup Behera, VIVEK
2025-12-08 23:53 ` [PATCH] igc: Fix trigger of incorrect irq in igc_xsk_wakeup function Jacob Keller
2025-12-09 6:03 ` Behera, VIVEK
2025-12-09 6:46 ` [PATCH v3 iwl-net] " Behera, VIVEK
2025-12-09 8:05 ` Loktionov, Aleksandr
2025-12-10 7:09 ` AW: [PATCH v4 " Behera, VIVEK
2025-12-10 7:16 ` [PATCH v3 " Loktionov, Aleksandr
2025-12-10 7:50 ` AW: [PATCH v5 " Behera, VIVEK
2025-12-10 8:57 ` Jakub Kicinski
2025-12-10 10:16 ` AW: " Kurt Kanzenbach
2025-12-10 16:41 ` [Intel-wired-lan] " Paul Menzel
2025-12-10 10:15 ` [PATCH v3 " Kwapulinski, Piotr
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).