Re: [PATCH 1/5] Add functions producing system time given a backing counter value
From: Thomas Gleixner <hidden>
Date: 2015-07-29 12:52:55
Also in:
lkml
On Wed, 29 Jul 2015, Peter Zijlstra wrote:
On Wed, Jul 29, 2015 at 12:19:06PM +0200, Thomas Gleixner wrote:quoted
I don't know whether we need functionality to convert arbitrary timestamps at all, but if we really need them then they are going to be pretty simple and explicitely not precise for anything else than clock monotonic raw. But that's a different story.I think we need that too, and agreed, given NTP anything other than MONO_RAW is going to be fuzzy at best.
Yes, but that's a trivial case.
quoted
+static u64 art_to_tsc(u64 cycles) +{ + /* FIXME: This needs 128bit math to work proper */ + return tsc_adjust + (cycles * tsc_numerator) / tsc_denominator;Yeah, its really unfortunate its given as a divisor and not a shift. That said I think, at least on the initial hardware, its 2, so: return mul_u64_u32_shr(cycles, tsc_numerator, 1); Should do, given that TSC_ADJUST had better be 0.
I don't trust BIOS folks :) + u64 tmp, res = tsc_adjust; + + res += (cycles / tsc_denominator) * tsc_numerator; + tmp = (cycles % tsc_denominator) * tsc_numerator; + res += tmp / tsc_denominator; + return res; That's what I have in my final patch.
quoted
+ do { + seq = read_seqcount_begin(&tk_core.seq); + /* + * Verify that the correlated clocksoure is related to + * the currently installed timekeeper clocksoure + */ + if (tk->tkr_mono.clock != crs->related_cs) + return -ENODEV; + + /* + * Try to get a timestamp from the device. + */ + ret = crt->get_ts(crt); + if (ret) + return ret; + + /* + * Convert the timestamp to timekeeper clock cycles + */ + cycles = crs->convert(crs, crt->system_ts); + + /* Convert to clock realtime */ + base = ktime_add(tk->tkr_mono.base, tk_core.timekeeper.offs_real); + nsecs = timekeeping_convert_to_ns(&tk->tkr_mono, cycles); + crt->system_real = ktime_add_ns(base, nsecs); + + /* Convert to clock raw monotonic */ + base = tk->tkr_raw.base; + nsecs = timekeeping_convert_to_ns(&tk->tkr_raw, cycles); + crt->system_raw = ktime_add_ns(base, nsecs); + + } while (read_seqcount_retry(&tk_core.seq, seq)); + return 0; +}This is still fuzzy, right? The hardware ART timestamp could be from _before_ the NTP adjust; or the NTP adjust could happen while we do this conversion and we'll take the retry loop.
I read the timestamp pair in the loop, so its always consistent.
Any other ART users (buffered ETH frames) the delay will only get bigger.
That's a different story and we really can only convert this to monotonic raw. Thanks, tglx