[Intel-wired-lan] [PATCH v1] e1000e: allow non-monotonic SYSTIM readings

Keller, Jacob E jacob.e.keller at intel.com
Tue Oct 23 16:32:50 UTC 2018


> -----Original Message-----
> From: Miroslav Lichvar [mailto:mlichvar at redhat.com]
> Sent: Tuesday, October 23, 2018 5:38 AM
> To: intel-wired-lan at lists.osuosl.org
> Cc: Miroslav Lichvar <mlichvar at redhat.com>; Keller, Jacob E
> <jacob.e.keller at intel.com>; Richard Cochran <richardcochran at gmail.com>
> Subject: [PATCH v1] e1000e: allow non-monotonic SYSTIM readings
> 
> It seems with some NICs supported by the e1000e driver a SYSTIM reading
> may occasionally be few microseconds before the previous reading and if
> enabled also pass e1000e_sanitize_systim() without reaching the maximum
> number of rereads, even if the function is modified to check three
> consecutive readings (i.e. it doesn't look like a double read error).
> This causes an underflow in the timecounter and the PHC time jumps hours
> ahead.
> 

Weird issue, but I think this is a better solution than returning garbage time data like we were before.

> This was observed on 82574, I217 and I219. The fastest way to reproduce
> it is to run a program that continuously calls the PTP_SYS_OFFSET ioctl
> on the PHC.
> 
> Modify e1000e_phc_gettime() to use timecounter_cyc2time() instead of
> timecounter_read() in order to allow non-monotonic SYSTIM readings and
> prevent the PHC from jumping.
> 

Thanks for the patch. This looks good to me.

Acked-by: Jacob Keller <jacob.e.keller at intel.com>

> Cc: Jacob Keller <jacob.e.keller at intel.com>
> Cc: Richard Cochran <richardcochran at gmail.com>
> Signed-off-by: Miroslav Lichvar <mlichvar at redhat.com>
> ---
> 
> Notes:
>     RFC->v1:
>     - Removed unnecessary call of PTP gettime64() in
>       e1000e_systim_overflow_work()
> 
>  drivers/net/ethernet/intel/e1000e/ptp.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c
> b/drivers/net/ethernet/intel/e1000e/ptp.c
> index 37c76945ad9b..e1f821edbc21 100644
> --- a/drivers/net/ethernet/intel/e1000e/ptp.c
> +++ b/drivers/net/ethernet/intel/e1000e/ptp.c
> @@ -173,10 +173,14 @@ static int e1000e_phc_gettime(struct ptp_clock_info *ptp,
> struct timespec64 *ts)
>  	struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
>  						     ptp_clock_info);
>  	unsigned long flags;
> -	u64 ns;
> +	u64 cycles, ns;
> 
>  	spin_lock_irqsave(&adapter->systim_lock, flags);
> -	ns = timecounter_read(&adapter->tc);
> +
> +	/* Use timecounter_cyc2time() to allow non-monotonic SYSTIM readings */
> +	cycles = adapter->cc.read(&adapter->cc);
> +	ns = timecounter_cyc2time(&adapter->tc, cycles);
> +
>  	spin_unlock_irqrestore(&adapter->systim_lock, flags);
> 
>  	*ts = ns_to_timespec64(ns);
> @@ -232,9 +236,12 @@ static void e1000e_systim_overflow_work(struct
> work_struct *work)
>  						     systim_overflow_work.work);
>  	struct e1000_hw *hw = &adapter->hw;
>  	struct timespec64 ts;
> +	u64 ns;
> 
> -	adapter->ptp_clock_info.gettime64(&adapter->ptp_clock_info, &ts);
> +	/* Update the timecounter */
> +	ns = timecounter_read(&adapter->tc);
> 
> +	ts = ns_to_timespec64(ns);
>  	e_dbg("SYSTIM overflow check at %lld.%09lu\n",
>  	      (long long) ts.tv_sec, ts.tv_nsec);
> 
> --
> 2.17.1



More information about the Intel-wired-lan mailing list