[Intel-wired-lan] [PATCH iwl-net v2 2/5] i40e: serialize timestamp configuration with PTP teardown
[email protected] Wed, 5 Aug 2026 14:51:29 +0800
| Newsgroups | org.osuosl.intel-wired-lan,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
From: Xuanqiang Luo <[email protected]> i40e_remove() can call i40e_ptp_stop() without the networking locks held. A concurrent hardware timestamp request can observe I40E_FLAG_PTP_ENA before teardown clears it, then program PRTTSYN_CTL0 after teardown has disabled the event source. This can leave time sync interrupts enabled during device removal. Add ptp_config_lock to serialize the enable check and register programming in i40e_ptp_hwtstamp_set() with the PTP state transition in i40e_ptp_stop(). Requests which observe PTP enabled finish programming before the state transition; later requests return -EOPNOTSUPP and cannot re-enable the interrupt. Fixes: 1050713026a0 ("i40e: add support for PTP external synchronization clock") Signed-off-by: Xuanqiang Luo <[email protected]> --- drivers/net/ethernet/intel/i40e/i40e.h | 2 ++ drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + drivers/net/ethernet/intel/i40e/i40e_ptp.c | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 4c8bcaa9dd192..84564d747d09a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -668,6 +668,8 @@ struct i40e_pf { struct timespec64 ptp_prev_hw_time; struct work_struct ptp_extts0_work; ktime_t ptp_reset_start; + /* Serializes timestamp configuration with PTP teardown. */ + struct mutex ptp_config_lock; struct mutex tmreg_lock; /* Used to protect the SYSTIME registers. */ u32 ptp_adj_mult; u32 tx_hwtstamp_timeouts; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0a259351c127e..8c28788ac634f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -12819,6 +12819,7 @@ static int i40e_sw_init(struct i40e_pf *pf) "total-port-shutdown was enabled, link-down-on-close is forced on\n"); } mutex_init(&pf->switch_mutex); + mutex_init(&pf->ptp_config_lock); spin_lock_init(&pf->ptp_tx_lock); sw_init_done: diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index 224568a3af085..f194869947124 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c @@ -1328,17 +1328,23 @@ int i40e_ptp_hwtstamp_set(struct net_device *netdev, struct i40e_pf *pf = np->vsi->back; int err; - if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags)) - return -EOPNOTSUPP; + mutex_lock(&pf->ptp_config_lock); + + if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags)) { + err = -EOPNOTSUPP; + goto unlock; + } err = i40e_ptp_set_timestamp_mode(pf, config); if (err) - return err; + goto unlock; /* save these settings for future reference */ pf->tstamp_config = *config; - return 0; +unlock: + mutex_unlock(&pf->ptp_config_lock); + return err; } /** @@ -1558,6 +1564,8 @@ void i40e_ptp_stop(struct i40e_pf *pf) struct sk_buff *skb; u32 regval; + mutex_lock(&pf->ptp_config_lock); + spin_lock_irqsave(&pf->ptp_tx_lock, flags); clear_bit(I40E_FLAG_PTP_ENA, pf->flags); pf->ptp_tx = false; @@ -1566,6 +1574,7 @@ void i40e_ptp_stop(struct i40e_pf *pf) spin_unlock_irqrestore(&pf->ptp_tx_lock, flags); pf->ptp_rx = false; + mutex_unlock(&pf->ptp_config_lock); if (skb) dev_kfree_skb_any(skb); -- 2.43.0