> -----Original Message-----
> From: Intel-wired-lan <[email protected]> On Behalf
> Of Chwee-Lin Choong
> Sent: Thursday, September 18, 2025 8:38 PM
> To: Nguyen, Anthony L <[email protected]>; Kitszel,
> Przemyslaw <[email protected]>; Andrew Lunn
> <[email protected]>; David S . Miller <[email protected]>; Eric
> Dumazet <[email protected]>; Jakub Kicinski <[email protected]>; Paolo
> Abeni <[email protected]>; Richard Cochran <[email protected]>;
> Gomes, Vinicius <[email protected]>
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Shalev, Avi <[email protected]>; Song,
> Yoong Siang <[email protected]>
> Subject: [Intel-wired-lan] [PATCH iwl-net v1] igc: fix race condition
> in TX timestamp read for register 0
> 
> The current HW bug workaround checks the TXTT_0 ready bit first, then
> reads LOW -> HIGH -> LOW from register 0 to detect if a timestamp was
> captured.
> 
> This sequence has a race: if a new timestamp is latched after reading
> the TXTT mask but before the first LOW read, both old and new
> timestamp match, causing the driver to drop a valid timestamp.
> 
> Fix by reading the LOW register first, then the TXTT mask, so a newly
> latched timestamp will always be detected.
> 
> This fix also prevents TX unit hangs observed under heavy timestamping
> load.
> 
> Fixes: c789ad7cbebc ("igc: Work around HW bug causing missing
> timestamps")
> Suggested-by: Avi Shalev <[email protected]>
> Signed-off-by: Song Yoong Siang <[email protected]>
> Signed-off-by: Chwee-Lin Choong <[email protected]>
> ---
>  drivers/net/ethernet/intel/igc/igc_ptp.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c
> b/drivers/net/ethernet/intel/igc/igc_ptp.c
> index b7b46d863bee..930486b02fc1 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ptp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
> @@ -774,10 +774,17 @@ static void igc_ptp_tx_reg_to_stamp(struct
> igc_adapter *adapter,  static void igc_ptp_tx_hwtstamp(struct
> igc_adapter *adapter)  {
>       struct igc_hw *hw = &adapter->hw;
> +     u32 txstmpl_old;
>       u64 regval;
>       u32 mask;
>       int i;
> 
> +     /* Read the "low" register 0 first to establish a baseline
> value.
> +      * This avoids a race where a new timestamp could be latched
> +      * after checking the TXTT mask.
> +      */
> +     txstmpl_old = rd32(IGC_TXSTMPL);
> +
>       mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY;
>       if (mask & IGC_TSYNCTXCTL_TXTT_0) {
>               regval = rd32(IGC_TXSTMPL);
> @@ -801,9 +808,8 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter
> *adapter)
>                * timestamp was captured, we can read the "high"
>                * register again.
>                */
> -             u32 txstmpl_old, txstmpl_new;
> +             u32 txstmpl_new;
> 
> -             txstmpl_old = rd32(IGC_TXSTMPL);
>               rd32(IGC_TXSTMPH);
>               txstmpl_new = rd32(IGC_TXSTMPL);
> 
> --
> 2.42.0

Reviewed-by: Aleksandr Loktionov <[email protected]>

Reply via email to