instability of timekeeping
Andriy Gapon
avg at FreeBSD.org
Wed Oct 21 08:43:18 UTC 2015
On 20/10/2015 14:05, Andriy Gapon wrote:
> I performed a small observation. With ntpd disabled I ran `ntpdate -d` at 10
> second intervals in a loop (done via `sleep 10`). It looks like for about 25
> minutes the time offset between a reference server and my machine was quite
> stable. But then it sort of jumped about 2.5 seconds between two consecutive
> ntpdate invocations.
[snip]
> On 20/10/2015 13:12, Andriy Gapon wrote:
[snip]
>> kern.timecounter.tc.TSC-low.frequency: 1607357461
>> kern.timecounter.tc.TSC-low.counter: 2457319922
>> kern.timecounter.tc.TSC-low.mask: 4294967295
[snip]
Another observation and a hypothesis.
I tried time counters other than TSC and I couldn't reproduce the issue with them.
Another thing that occurred to me is that TSC-low.mask / TSC-low.frequency ≈ 2.7
seconds.
>From these observations and reading some code comes my hypothesis.
First, I assume that visible values of TSCs on different cores are not perfectly
synchronized. Second, I think that there can be circumstances where
tc_ticktock() -> tc_windup() can get called on different cores sufficiently
close in time that the later call would see TSC value which is "before"
(sequentially smaller) than the TSC value read earlier (on the other core). In
that case the delta between the readings would be close to TSC-low.mask.
Right now I do not have any proof that what the hypothesis says is what actually
happens. On the other hand, I do not see anything that would prevent the
hypothesized situation from occurring.
To add more weight to the hypothesis:
cpu1:invltlb 674384 4
cpu1:invlrng 453020 3
cpu1:invlpg 108772578 652
cpu1:preempt 37435000 224
cpu1:ast 36757 0
cpu1:rendezvous 9473 0
cpu1:hardclock 22267434 133
As you can see I am currently running workloads that result in a very
significant number of IPIs, especially the page invalidation IPIs. Given that
all (x86) IPIs have the same priority (based on their vector numbers) I think
it's plausible that the hardclock IPI could get arbitrarily delayed.
I guess I could add a tracepoint to record deltas that are close to a current
timecounter's mask.
Assuming the hypothesis is correct I see two possible ways to work-around the
problem:
1. Increase tsc_shift, so that the cross-CPU TSC differences are smaller (at the
cost of lower resolution). That should reduce the risk of seeing "backwards"
TSC values. Judging from numbers that tools/tools/tscdrift produces I can set
tsc_shift to 7. The resulting resolution should not be worse than that of HPET
or ACPI-fast counters with the benefit of TSC being much faster to read.
2. Change the code, so that tc_windup() is always called on the same CPU. E.g.
it could be the BSP or a CPU that receives the actual timer interrupts (as
opposed to the hardclock IPIs). This should help with the timekeeping, but
won't help with the "jitter" in binuptime() and friends.
3. In tc_delta() somehow detect and filter out "slightly behind" timecounter
readings. Not sure if this is possible at all.
--
Andriy Gapon
More information about the freebsd-hackers
mailing list