lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
 <AS1PR10MB539280B1427DA0ABE9D65E628FA5A@AS1PR10MB5392.EURPRD10.PROD.OUTLOOK.COM>
Date: Sun, 7 Dec 2025 15:46:48 +0000
From: "Behera, VIVEK" <vivek.behera@...mens.com>
To: Tony Nguyen <anthony.l.nguyen@...el.com>, Przemek Kitszel
	<przemyslaw.kitszel@...el.com>, Andrew Lunn <andrew+netdev@...n.ch>, "\"David
 S. Miller\"" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>, Jakub
 Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>
CC: "intel-wired-lan@...ts.osuosl.org" <intel-wired-lan@...ts.osuosl.org>,
	"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>, "Behera,
 VIVEK" <vivek.behera@...mens.com>
Subject: RE:  [PATCH v2] igc: Enhance xsk wakeup for split IRQ and fix PTP TX
 wakeup

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@...mens.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@...mens.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ