Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: maxime.ripard@bootlin.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] arm64: arch_timer: Workaround for Allwinner A64 timer instability
Date: Fri, 11 May 2018 10:26:53 +0200	[thread overview]
Message-ID: <20180511082653.qhfdjliofmelmtwp@flea> (raw)
In-Reply-To: <20180511022751.9096-2-samuel@sholland.org>

On Thu, May 10, 2018 at 09:27:50PM -0500, Samuel Holland wrote:
> The Allwinner A64 SoC is known [1] to have an unstable architectural
> timer, which manifests itself most obviously in the time jumping forward
> a multiple of 95 years [2][3]. This coincides with 2^56 cycles at a
> timer frequency of 24 MHz, implying that the time went slightly backward
> (and this was interpreted by the kernel as it jumping forward and
> wrapping around past the epoch).
> 
> Further investigation revealed instability in the low bits of CNTVCT at
> the point a high bit rolls over. This leads to power-of-two cycle
> forward and backward jumps. (Testing shows that forward jumps are about
> twice as likely as backward jumps.)
> 
> Without trapping reads to CNTVCT, a userspace program is able to read it
> in a loop faster than it changes. A test program running on all 4 CPU
> cores that reported jumps larger than 100 ms was run for 13.6 hours and
> reported the following:
> 
>  Count | Event
> -------+---------------------------
>   9940 | jumped backward      699ms
>    268 | jumped backward     1398ms
>      1 | jumped backward     2097ms
>  16020 | jumped forward       175ms
>   6443 | jumped forward       699ms
>   2976 | jumped forward      1398ms
>      9 | jumped forward    356516ms
>      9 | jumped forward    357215ms
>      4 | jumped forward    714430ms
>      1 | jumped forward   3578440ms
> 
> This works out to a jump larger than 100 ms about every 5.5 seconds on
> each CPU core.
> 
> The largest jump (almost an hour!) was the following sequence of reads:
>       0x0000007fffffffff ? 0x00000093feffffff ? 0x0000008000000000
> 
> Note that the middle bits don't necessarily all read as all zeroes or
> all ones during the anomalous behavior; however the low 11 bits checked
> by the function in this patch have never been observed with any other
> value.
> 
> Also note that smaller jumps are much more common, with the smallest
> backward jumps of 2048 cycles observed over 400 times per second on each
> core. (Of course, this is partially due to lower bits rolling over more
> frequently.) Any one of these could have caused the 95 year time skip.
> 
> Similar anomalies were observed while reading CNTPCT (after patching the
> kernel to allow reads from userspace). However, the jumps are much less
> frequent, and only small jumps were observed. The same program as before
> (except now reading CNTPCT) observed after 72 hours:
> 
>  Count | Event
> -------+---------------------------
>     17 | jumped backward      699ms
>     52 | jumped forward       175ms
>   2831 | jumped forward       699ms
>      5 | jumped forward      1398ms
> 
> ========================================================================
> 
> Because the CPU can read the CNTPCT/CNTVCT registers faster than they
> change, performing two reads of the register and comparing the high bits
> (like other workarounds) is not a workable solution. And because the
> timer can jump both forward and backward, no pair of reads can
> distinguish a good value from a bad one. The only way to guarantee a
> good value from consecutive reads would be to read _three_ times, and
> take the middle value iff the three values are 1) individually unique
> and 2) increasing. This takes at minimum 3 cycles (125 ns), or more if
> an anomaly is detected.
> 
> However, since there is a distinct pattern to the bad values, we can
> optimize the common case (2046/2048 of the time) to a single read by
> simply ignoring values that match the pattern. This still takes no more
> than 3 cycles in the worst case, and requires much less code.

That's an awesome commit log, thanks!

For both patches:
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>

> [1]: https://github.com/armbian/build/commit/a08cd6fe7ae9
> [2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/

Sigh. So armbian knew about this for more than a year and had a fix,
and didn't judge necessary to report it anywhere. That's some solid,
responsible, development right there...

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180511/3e662f74/attachment-0001.sig>

  reply	other threads:[~2018-05-11  8:26 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-11  2:27 [PATCH 0/2] Allwinner A64 timer workaround Samuel Holland
2018-05-11  2:27 ` [PATCH 1/2] arm64: arch_timer: Workaround for Allwinner A64 timer instability Samuel Holland
2018-05-11  8:26   ` Maxime Ripard [this message]
2018-05-11  8:48   ` Marc Zyngier
2018-05-11 15:08     ` Samuel Holland
2018-05-26 15:15   ` André Przywara
2018-05-11  2:27 ` [PATCH 2/2] arm64: dts: allwinner: a64: Enable A64 timer workaround Samuel Holland
2018-05-11  9:24 ` [PATCH 0/2] Allwinner " Andre Przywara
2018-07-03 15:09 ` Marc Zyngier
2018-07-03 18:42   ` Samuel Holland
2018-07-04  8:16     ` Marc Zyngier
2018-07-04  8:19       ` Chen-Yu Tsai
2018-07-04  8:23       ` Daniel Lezcano
2018-07-04  8:39         ` Marc Zyngier
2018-07-04 10:00           ` Thomas Gleixner
2018-07-04 13:08             ` [linux-sunxi] " Andre Przywara
2018-07-04 14:31               ` Thomas Gleixner
2018-07-04 14:44                 ` Andre Przywara
2018-07-04 15:01                   ` Marc Zyngier
2018-07-04 15:15                     ` Andre Przywara
2018-07-04 15:30                       ` Marc Zyngier
2018-07-04 15:23                     ` Samuel Holland
2018-07-04 15:14                   ` Thomas Gleixner
2018-07-04 15:43                     ` Andre Przywara
2018-07-04 19:49                       ` Thomas Gleixner
2018-07-04  8:41       ` Daniel Lezcano
2018-07-12  2:23         ` Samuel Holland
2018-07-04  9:06       ` Maxime Ripard
2018-07-04  8:41     ` Daniel Lezcano
2018-07-04 12:52     ` [linux-sunxi] " Andre Przywara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180511082653.qhfdjliofmelmtwp@flea \
    --to=maxime.ripard@bootlin.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox