linux/drivers/net/dsa/sja1105
Vladimir Oltean b6f2494d31 net: dsa: sja1105: Ensure PTP time for rxtstamp reconstruction is not in the past
Sometimes the PTP synchronization on the switch 'jumps':

  ptp4l[11241.155]: rms    8 max   16 freq -21732 +/-  11 delay   742 +/-   0
  ptp4l[11243.157]: rms    7 max   17 freq -21731 +/-  10 delay   744 +/-   0
  ptp4l[11245.160]: rms 33592410 max 134217731 freq +192422 +/- 8530253 delay   743 +/-   0
  ptp4l[11247.163]: rms 811631 max 964131 freq +10326 +/- 557785 delay   743 +/-   0
  ptp4l[11249.166]: rms 261936 max 533876 freq -304323 +/- 126371 delay   744 +/-   0
  ptp4l[11251.169]: rms 48700 max 57740 freq -20218 +/- 30532 delay   744 +/-   0
  ptp4l[11253.171]: rms 14570 max 30163 freq  -5568 +/- 7563 delay   742 +/-   0
  ptp4l[11255.174]: rms 2914 max 3440 freq -22001 +/- 1667 delay   744 +/-   1
  ptp4l[11257.177]: rms  811 max 1710 freq -22653 +/- 451 delay   744 +/-   1
  ptp4l[11259.180]: rms  177 max  218 freq -21695 +/-  89 delay   741 +/-   0
  ptp4l[11261.182]: rms   45 max   92 freq -21677 +/-  32 delay   742 +/-   0
  ptp4l[11263.186]: rms   14 max   32 freq -21733 +/-  11 delay   742 +/-   0
  ptp4l[11265.188]: rms    9 max   14 freq -21725 +/-  12 delay   742 +/-   0
  ptp4l[11267.191]: rms    9 max   16 freq -21727 +/-  13 delay   742 +/-   0
  ptp4l[11269.194]: rms    6 max   15 freq -21726 +/-   9 delay   743 +/-   0
  ptp4l[11271.197]: rms    8 max   15 freq -21728 +/-  11 delay   743 +/-   0
  ptp4l[11273.200]: rms    6 max   12 freq -21727 +/-   8 delay   743 +/-   0
  ptp4l[11275.202]: rms    9 max   17 freq -21720 +/-  11 delay   742 +/-   0
  ptp4l[11277.205]: rms    9 max   18 freq -21725 +/-  12 delay   742 +/-   0

Background: the switch only offers partial RX timestamps (24 bits) and
it is up to the driver to read the PTP clock to fill those timestamps up
to 64 bits. But the PTP clock readout needs to happen quickly enough (in
0.135 seconds, in fact), otherwise the PTP clock will wrap around 24
bits, condition which cannot be detected.

Looking at the 'max 134217731' value on output line 3, one can see that
in hex it is 0x8000003. Because the PTP clock resolution is 8 ns,
that means 0x1000000 in ticks, which is exactly 2^24. So indeed this is
a PTP clock wraparound, but the reason might be surprising.

What is going on is that sja1105_tstamp_reconstruct(priv, now, ts)
expects a "now" time that is later than the "ts" was snapshotted at.
This, of course, is obvious: we read the PTP time _after_ the partial RX
timestamp was received. However, the workqueue is processing frames from
a skb queue and reuses the same PTP time, read once at the beginning.
Normally the skb queue only contains one frame and all goes well. But
when the skb queue contains two frames, the second frame that gets
dequeued might have been partially timestamped by the RX MAC _after_ we
had read our PTP time initially.

The code was originally like that due to concerns that SPI access for
PTP time readout is a slow process, and we are time-constrained anyway
(aka: premature optimization). But some timing analysis reveals that the
time spent until the RX timestamp is completely reconstructed is 1 order
of magnitude lower than the 0.135 s deadline even under worst-case
conditions. So we can afford to read the PTP time for each frame in the
RX timestamping queue, which of course ensures that the full PTP time is
in the partial timestamp's future.

Fixes: f3097be21b ("net: dsa: sja1105: Add a state machine for RX timestamping")
Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-09-30 17:20:50 -07:00
..
Kconfig net: dsa: sja1105: Add dependency for NET_DSA_SJA1105_TAS 2019-09-21 19:41:19 -07:00
Makefile net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload 2019-09-16 21:32:58 +02:00
sja1105_clocking.c net: dsa: sja1105: Add RGMII delay support for P/Q/R/S chips 2019-06-09 20:06:54 -07:00
sja1105_dynamic_config.c net: dsa: sja1105: Add static config tables for scheduling 2019-09-16 21:32:57 +02:00
sja1105_dynamic_config.h net: dsa: sja1105: Plug in support for TCAM searches via the dynamic interface 2019-06-04 11:49:19 -07:00
sja1105_ethtool.c net: dsa: sja1105: Fix status initialization in sja1105_get_ethtool_stats 2019-05-07 12:20:46 -07:00
sja1105_main.c net: dsa: sja1105: Ensure PTP time for rxtstamp reconstruction is not in the past 2019-09-30 17:20:50 -07:00
sja1105_ptp.c net: dsa: sja1105: Really fix panic on unregistering PTP clock 2019-08-06 14:37:02 -07:00
sja1105_ptp.h net: dsa: sja1105: Add logic for TX timestamping 2019-06-08 15:20:40 -07:00
sja1105_spi.c net: dsa: sja1105: Build PTP support in main DSA driver 2019-06-27 11:03:21 -07:00
sja1105_static_config.c net: dsa: sja1105: Add static config tables for scheduling 2019-09-16 21:32:57 +02:00
sja1105_static_config.h net: dsa: sja1105: Add static config tables for scheduling 2019-09-16 21:32:57 +02:00
sja1105_tas.c net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload 2019-09-16 21:32:58 +02:00
sja1105_tas.h net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload 2019-09-16 21:32:58 +02:00
sja1105.h net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload 2019-09-16 21:32:58 +02:00