diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2016-12-01 13:57:58 -0800 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2016-12-01 13:57:58 -0800 |
commit | fa40ddf73c5d6c5c57fc6e79833ec48eb99cbf52 (patch) | |
tree | 977559221fb383bdcf337df9a52d6998eaa4f70f /kernel/time | |
parent | f225dbdca9127536b7296778b3b0cfd96f65df00 (diff) | |
parent | 25dcb75878cd3b685a70c688758a4d3726e92703 (diff) |
Merge remote-tracking branch 'common/android-4.4' into android-4.4.y
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/timekeeping.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 445601c580d6..ede4bf13d3e9 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -424,6 +424,35 @@ u64 ktime_get_raw_fast_ns(void) } EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns); +/** + * ktime_get_boot_fast_ns - NMI safe and fast access to boot clock. + * + * To keep it NMI safe since we're accessing from tracing, we're not using a + * separate timekeeper with updates to monotonic clock and boot offset + * protected with seqlocks. This has the following minor side effects: + * + * (1) Its possible that a timestamp be taken after the boot offset is updated + * but before the timekeeper is updated. If this happens, the new boot offset + * is added to the old timekeeping making the clock appear to update slightly + * earlier: + * CPU 0 CPU 1 + * timekeeping_inject_sleeptime64() + * __timekeeping_inject_sleeptime(tk, delta); + * timestamp(); + * timekeeping_update(tk, TK_CLEAR_NTP...); + * + * (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be + * partially updated. Since the tk->offs_boot update is a rare event, this + * should be a rare occurrence which postprocessing should be able to handle. + */ +u64 notrace ktime_get_boot_fast_ns(void) +{ + struct timekeeper *tk = &tk_core.timekeeper; + + return (ktime_get_mono_fast_ns() + ktime_to_ns(tk->offs_boot)); +} +EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); + /* Suspend-time cycles value for halted fast timekeeper. */ static cycle_t cycles_at_suspend; |