aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 6a92794427c9..8af77006e937 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -496,6 +496,39 @@ u64 notrace ktime_get_boot_fast_ns(void)
496} 496}
497EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns); 497EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
498 498
499
500/*
501 * See comment for __ktime_get_fast_ns() vs. timestamp ordering
502 */
503static __always_inline u64 __ktime_get_real_fast_ns(struct tk_fast *tkf)
504{
505 struct tk_read_base *tkr;
506 unsigned int seq;
507 u64 now;
508
509 do {
510 seq = raw_read_seqcount_latch(&tkf->seq);
511 tkr = tkf->base + (seq & 0x01);
512 now = ktime_to_ns(tkr->base_real);
513
514 now += timekeeping_delta_to_ns(tkr,
515 clocksource_delta(
516 tk_clock_read(tkr),
517 tkr->cycle_last,
518 tkr->mask));
519 } while (read_seqcount_retry(&tkf->seq, seq));
520
521 return now;
522}
523
524/**
525 * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime.
526 */
527u64 ktime_get_real_fast_ns(void)
528{
529 return __ktime_get_real_fast_ns(&tk_fast_mono);
530}
531
499/** 532/**
500 * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. 533 * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
501 * @tk: Timekeeper to snapshot. 534 * @tk: Timekeeper to snapshot.
@@ -514,6 +547,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)
514 memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy)); 547 memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
515 cycles_at_suspend = tk_clock_read(tkr); 548 cycles_at_suspend = tk_clock_read(tkr);
516 tkr_dummy.clock = &dummy_clock; 549 tkr_dummy.clock = &dummy_clock;
550 tkr_dummy.base_real = tkr->base + tk->offs_real;
517 update_fast_timekeeper(&tkr_dummy, &tk_fast_mono); 551 update_fast_timekeeper(&tkr_dummy, &tk_fast_mono);
518 552
519 tkr = &tk->tkr_raw; 553 tkr = &tk->tkr_raw;
@@ -661,6 +695,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
661 update_vsyscall(tk); 695 update_vsyscall(tk);
662 update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET); 696 update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
663 697
698 tk->tkr_mono.base_real = tk->tkr_mono.base + tk->offs_real;
664 update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono); 699 update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
665 update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw); 700 update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
666 701