diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
| -rw-r--r-- | kernel/time/timekeeping.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index a413e5940e06..1c038dac71a2 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -70,6 +70,12 @@ struct timekeeper { | |||
| 70 | /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ | 70 | /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ |
| 71 | struct timespec raw_time; | 71 | struct timespec raw_time; |
| 72 | 72 | ||
| 73 | /* Offset clock monotonic -> clock realtime */ | ||
| 74 | ktime_t offs_real; | ||
| 75 | |||
| 76 | /* Offset clock monotonic -> clock boottime */ | ||
| 77 | ktime_t offs_boot; | ||
| 78 | |||
| 73 | /* Seqlock for all timekeeper values */ | 79 | /* Seqlock for all timekeeper values */ |
| 74 | seqlock_t lock; | 80 | seqlock_t lock; |
| 75 | }; | 81 | }; |
| @@ -172,6 +178,14 @@ static inline s64 timekeeping_get_ns_raw(void) | |||
| 172 | return clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); | 178 | return clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); |
| 173 | } | 179 | } |
| 174 | 180 | ||
| 181 | static void update_rt_offset(void) | ||
| 182 | { | ||
| 183 | struct timespec tmp, *wtm = &timekeeper.wall_to_monotonic; | ||
| 184 | |||
| 185 | set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec); | ||
| 186 | timekeeper.offs_real = timespec_to_ktime(tmp); | ||
| 187 | } | ||
| 188 | |||
| 175 | /* must hold write on timekeeper.lock */ | 189 | /* must hold write on timekeeper.lock */ |
| 176 | static void timekeeping_update(bool clearntp) | 190 | static void timekeeping_update(bool clearntp) |
| 177 | { | 191 | { |
| @@ -179,6 +193,7 @@ static void timekeeping_update(bool clearntp) | |||
| 179 | timekeeper.ntp_error = 0; | 193 | timekeeper.ntp_error = 0; |
| 180 | ntp_clear(); | 194 | ntp_clear(); |
| 181 | } | 195 | } |
| 196 | update_rt_offset(); | ||
| 182 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, | 197 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 183 | timekeeper.clock, timekeeper.mult); | 198 | timekeeper.clock, timekeeper.mult); |
| 184 | } | 199 | } |
| @@ -604,6 +619,7 @@ void __init timekeeping_init(void) | |||
| 604 | } | 619 | } |
| 605 | set_normalized_timespec(&timekeeper.wall_to_monotonic, | 620 | set_normalized_timespec(&timekeeper.wall_to_monotonic, |
| 606 | -boot.tv_sec, -boot.tv_nsec); | 621 | -boot.tv_sec, -boot.tv_nsec); |
| 622 | update_rt_offset(); | ||
| 607 | timekeeper.total_sleep_time.tv_sec = 0; | 623 | timekeeper.total_sleep_time.tv_sec = 0; |
| 608 | timekeeper.total_sleep_time.tv_nsec = 0; | 624 | timekeeper.total_sleep_time.tv_nsec = 0; |
| 609 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 625 | write_sequnlock_irqrestore(&timekeeper.lock, flags); |
| @@ -612,6 +628,12 @@ void __init timekeeping_init(void) | |||
| 612 | /* time in seconds when suspend began */ | 628 | /* time in seconds when suspend began */ |
| 613 | static struct timespec timekeeping_suspend_time; | 629 | static struct timespec timekeeping_suspend_time; |
| 614 | 630 | ||
| 631 | static void update_sleep_time(struct timespec t) | ||
| 632 | { | ||
| 633 | timekeeper.total_sleep_time = t; | ||
| 634 | timekeeper.offs_boot = timespec_to_ktime(t); | ||
| 635 | } | ||
| 636 | |||
| 615 | /** | 637 | /** |
| 616 | * __timekeeping_inject_sleeptime - Internal function to add sleep interval | 638 | * __timekeeping_inject_sleeptime - Internal function to add sleep interval |
| 617 | * @delta: pointer to a timespec delta value | 639 | * @delta: pointer to a timespec delta value |
| @@ -630,8 +652,7 @@ static void __timekeeping_inject_sleeptime(struct timespec *delta) | |||
| 630 | timekeeper.xtime = timespec_add(timekeeper.xtime, *delta); | 652 | timekeeper.xtime = timespec_add(timekeeper.xtime, *delta); |
| 631 | timekeeper.wall_to_monotonic = | 653 | timekeeper.wall_to_monotonic = |
| 632 | timespec_sub(timekeeper.wall_to_monotonic, *delta); | 654 | timespec_sub(timekeeper.wall_to_monotonic, *delta); |
| 633 | timekeeper.total_sleep_time = timespec_add( | 655 | update_sleep_time(timespec_add(timekeeper.total_sleep_time, *delta)); |
| 634 | timekeeper.total_sleep_time, *delta); | ||
| 635 | } | 656 | } |
| 636 | 657 | ||
| 637 | 658 | ||
