Skip to content

Commit ed4420a

Browse files
kuba-mooJeff Kirsher
authored andcommitted
igb: fix race conditions on queuing skb for HW time stamp
igb has a single set of TX time stamping resources per NIC. Use a simple bit lock to avoid race conditions and leaking skbs when multiple TX rings try to claim time stamping. Signed-off-by: Jakub Kicinski <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent afc835d commit ed4420a

File tree

3 files changed

+7
-2
lines changed

3 files changed

+7
-2
lines changed

drivers/net/ethernet/intel/igb/igb.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,8 @@ struct igb_adapter {
492492
enum e1000_state_t {
493493
__IGB_TESTING,
494494
__IGB_RESETTING,
495-
__IGB_DOWN
495+
__IGB_DOWN,
496+
__IGB_PTP_TX_IN_PROGRESS,
496497
};
497498

498499
enum igb_boards {

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4983,7 +4983,8 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
49834983
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
49844984
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
49854985

4986-
if (!(adapter->ptp_tx_skb)) {
4986+
if (!test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS,
4987+
&adapter->state)) {
49874988
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
49884989
tx_flags |= IGB_TX_FLAGS_TSTAMP;
49894990

drivers/net/ethernet/intel/igb/igb_ptp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ static void igb_ptp_tx_work(struct work_struct *work)
387387
IGB_PTP_TX_TIMEOUT)) {
388388
dev_kfree_skb_any(adapter->ptp_tx_skb);
389389
adapter->ptp_tx_skb = NULL;
390+
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
390391
adapter->tx_hwtstamp_timeouts++;
391392
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
392393
return;
@@ -480,6 +481,7 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
480481
skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
481482
dev_kfree_skb_any(adapter->ptp_tx_skb);
482483
adapter->ptp_tx_skb = NULL;
484+
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
483485
}
484486

485487
/**
@@ -857,6 +859,7 @@ void igb_ptp_stop(struct igb_adapter *adapter)
857859
if (adapter->ptp_tx_skb) {
858860
dev_kfree_skb_any(adapter->ptp_tx_skb);
859861
adapter->ptp_tx_skb = NULL;
862+
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
860863
}
861864

862865
if (adapter->ptp_clock) {

0 commit comments

Comments
 (0)