Skip to content
/ linux Public

Commit 31521c1

Browse files
zdenek-bouskagregkh
authored andcommitted
igc: fix page fault in XDP TX timestamps handling
[ Upstream commit 45b33e8 ] If an XDP application that requested TX timestamping is shutting down while the link of the interface in use is still up the following kernel splat is reported: [ 883.803618] [ T1554] BUG: unable to handle page fault for address: ffffcfb6200fd008 ... [ 883.803650] [ T1554] Call Trace: [ 883.803652] [ T1554] <TASK> [ 883.803654] [ T1554] igc_ptp_tx_tstamp_event+0xdf/0x160 [igc] [ 883.803660] [ T1554] igc_tsync_interrupt+0x2d5/0x300 [igc] ... During shutdown of the TX ring the xsk_meta pointers are left behind, so that the IRQ handler is trying to touch them. This issue is now being fixed by cleaning up the stale xsk meta data on TX shutdown. TX timestamps on other queues remain unaffected. Fixes: 15fd021 ("igc: Add Tx hardware timestamp request for AF_XDP zero-copy packet") Signed-off-by: Zdenek Bouska <zdenek.bouska@siemens.com> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Reviewed-by: Florian Bezdeka <florian.bezdeka@siemens.com> Tested-by: Avigail Dahan <avigailx.dahan@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3472c22 commit 31521c1

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,8 @@ int igc_ptp_hwtstamp_set(struct net_device *netdev,
781781
struct kernel_hwtstamp_config *config,
782782
struct netlink_ext_ack *extack);
783783
void igc_ptp_tx_hang(struct igc_adapter *adapter);
784+
void igc_ptp_clear_xsk_tx_tstamp_queue(struct igc_adapter *adapter,
785+
u16 queue_id);
784786
void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts);
785787
void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter);
786788

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,13 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
264264
/* reset next_to_use and next_to_clean */
265265
tx_ring->next_to_use = 0;
266266
tx_ring->next_to_clean = 0;
267+
268+
/* Clear any lingering XSK TX timestamp requests */
269+
if (test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags)) {
270+
struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
271+
272+
igc_ptp_clear_xsk_tx_tstamp_queue(adapter, tx_ring->queue_index);
273+
}
267274
}
268275

269276
/**

drivers/net/ethernet/intel/igc/igc_ptp.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,39 @@ static void igc_ptp_clear_tx_tstamp(struct igc_adapter *adapter)
576576
spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
577577
}
578578

579+
/**
580+
* igc_ptp_clear_xsk_tx_tstamp_queue - Clear pending XSK TX timestamps for a queue
581+
* @adapter: Board private structure
582+
* @queue_id: TX queue index to clear timestamps for
583+
*
584+
* Iterates over all TX timestamp registers and releases any pending
585+
* timestamp requests associated with the given TX queue. This is
586+
* called when an XDP pool is being disabled to ensure no stale
587+
* timestamp references remain.
588+
*/
589+
void igc_ptp_clear_xsk_tx_tstamp_queue(struct igc_adapter *adapter, u16 queue_id)
590+
{
591+
unsigned long flags;
592+
int i;
593+
594+
spin_lock_irqsave(&adapter->ptp_tx_lock, flags);
595+
596+
for (i = 0; i < IGC_MAX_TX_TSTAMP_REGS; i++) {
597+
struct igc_tx_timestamp_request *tstamp = &adapter->tx_tstamp[i];
598+
599+
if (tstamp->buffer_type != IGC_TX_BUFFER_TYPE_XSK)
600+
continue;
601+
if (tstamp->xsk_queue_index != queue_id)
602+
continue;
603+
if (!tstamp->xsk_tx_buffer)
604+
continue;
605+
606+
igc_ptp_free_tx_buffer(adapter, tstamp);
607+
}
608+
609+
spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);
610+
}
611+
579612
static void igc_ptp_disable_tx_timestamp(struct igc_adapter *adapter)
580613
{
581614
struct igc_hw *hw = &adapter->hw;

0 commit comments

Comments
 (0)