diff options
| author | John Stultz <john.stultz@linaro.org> | 2011-11-14 14:29:32 -0500 |
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2012-01-26 22:44:09 -0500 |
| commit | d9f7217aac6833cc634741f2f771a87fd1518fee (patch) | |
| tree | 284a9a1597ec2166a0d2b43d108f1262be1f6b88 /kernel/time | |
| parent | 00c5fb774e3fa8c9d082c62eac7e3d178c006f56 (diff) | |
time: Move wall_to_monotonic into the timekeeper structure
In preparation for locking cleanups, move wall_to_monotonic
into the timekeeper structure.
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/timekeeping.c | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 8427cc20bad6..5655ca3a86d7 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -48,6 +48,21 @@ struct timekeeper { | |||
| 48 | /* NTP adjusted clock multiplier */ | 48 | /* NTP adjusted clock multiplier */ |
| 49 | u32 mult; | 49 | u32 mult; |
| 50 | 50 | ||
| 51 | /* | ||
| 52 | * wall_to_monotonic is what we need to add to xtime (or xtime corrected | ||
| 53 | * for sub jiffie times) to get to monotonic time. Monotonic is pegged | ||
| 54 | * at zero at system boot time, so wall_to_monotonic will be negative, | ||
| 55 | * however, we will ALWAYS keep the tv_nsec part positive so we can use | ||
| 56 | * the usual normalization. | ||
| 57 | * | ||
| 58 | * wall_to_monotonic is moved after resume from suspend for the | ||
| 59 | * monotonic time not to jump. We need to add total_sleep_time to | ||
| 60 | * wall_to_monotonic to get the real boot based time offset. | ||
| 61 | * | ||
| 62 | * - wall_to_monotonic is no longer the boot time, getboottime must be | ||
| 63 | * used instead. | ||
| 64 | */ | ||
| 65 | struct timespec wall_to_monotonic; | ||
| 51 | /* time spent in suspend */ | 66 | /* time spent in suspend */ |
| 52 | struct timespec total_sleep_time; | 67 | struct timespec total_sleep_time; |
| 53 | 68 | ||
| @@ -148,21 +163,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | |||
| 148 | 163 | ||
| 149 | /* | 164 | /* |
| 150 | * The current time | 165 | * The current time |
| 151 | * wall_to_monotonic is what we need to add to xtime (or xtime corrected | ||
| 152 | * for sub jiffie times) to get to monotonic time. Monotonic is pegged | ||
| 153 | * at zero at system boot time, so wall_to_monotonic will be negative, | ||
| 154 | * however, we will ALWAYS keep the tv_nsec part positive so we can use | ||
| 155 | * the usual normalization. | ||
| 156 | * | ||
| 157 | * wall_to_monotonic is moved after resume from suspend for the monotonic | ||
| 158 | * time not to jump. We need to add total_sleep_time to wall_to_monotonic | ||
| 159 | * to get the real boot based time offset. | ||
| 160 | * | ||
| 161 | * - wall_to_monotonic is no longer the boot time, getboottime must be | ||
| 162 | * used instead. | ||
| 163 | */ | 166 | */ |
| 164 | static struct timespec xtime __attribute__ ((aligned (16))); | 167 | static struct timespec xtime __attribute__ ((aligned (16))); |
| 165 | static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | ||
| 166 | 168 | ||
| 167 | /* | 169 | /* |
| 168 | * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. | 170 | * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. |
| @@ -176,8 +178,8 @@ int __read_mostly timekeeping_suspended; | |||
| 176 | void timekeeping_leap_insert(int leapsecond) | 178 | void timekeeping_leap_insert(int leapsecond) |
| 177 | { | 179 | { |
| 178 | xtime.tv_sec += leapsecond; | 180 | xtime.tv_sec += leapsecond; |
| 179 | wall_to_monotonic.tv_sec -= leapsecond; | 181 | timekeeper.wall_to_monotonic.tv_sec -= leapsecond; |
| 180 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | 182 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, |
| 181 | timekeeper.mult); | 183 | timekeeper.mult); |
| 182 | } | 184 | } |
| 183 | 185 | ||
| @@ -249,8 +251,8 @@ ktime_t ktime_get(void) | |||
| 249 | 251 | ||
| 250 | do { | 252 | do { |
| 251 | seq = read_seqbegin(&xtime_lock); | 253 | seq = read_seqbegin(&xtime_lock); |
| 252 | secs = xtime.tv_sec + wall_to_monotonic.tv_sec; | 254 | secs = xtime.tv_sec + timekeeper.wall_to_monotonic.tv_sec; |
| 253 | nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec; | 255 | nsecs = xtime.tv_nsec + timekeeper.wall_to_monotonic.tv_nsec; |
| 254 | nsecs += timekeeping_get_ns(); | 256 | nsecs += timekeeping_get_ns(); |
| 255 | /* If arch requires, add in gettimeoffset() */ | 257 | /* If arch requires, add in gettimeoffset() */ |
| 256 | nsecs += arch_gettimeoffset(); | 258 | nsecs += arch_gettimeoffset(); |
| @@ -283,7 +285,7 @@ void ktime_get_ts(struct timespec *ts) | |||
| 283 | do { | 285 | do { |
| 284 | seq = read_seqbegin(&xtime_lock); | 286 | seq = read_seqbegin(&xtime_lock); |
| 285 | *ts = xtime; | 287 | *ts = xtime; |
| 286 | tomono = wall_to_monotonic; | 288 | tomono = timekeeper.wall_to_monotonic; |
| 287 | nsecs = timekeeping_get_ns(); | 289 | nsecs = timekeeping_get_ns(); |
| 288 | /* If arch requires, add in gettimeoffset() */ | 290 | /* If arch requires, add in gettimeoffset() */ |
| 289 | nsecs += arch_gettimeoffset(); | 291 | nsecs += arch_gettimeoffset(); |
| @@ -374,14 +376,15 @@ int do_settimeofday(const struct timespec *tv) | |||
| 374 | 376 | ||
| 375 | ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec; | 377 | ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec; |
| 376 | ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec; | 378 | ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec; |
| 377 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts_delta); | 379 | timekeeper.wall_to_monotonic = |
| 380 | timespec_sub(timekeeper.wall_to_monotonic, ts_delta); | ||
| 378 | 381 | ||
| 379 | xtime = *tv; | 382 | xtime = *tv; |
| 380 | 383 | ||
| 381 | timekeeper.ntp_error = 0; | 384 | timekeeper.ntp_error = 0; |
| 382 | ntp_clear(); | 385 | ntp_clear(); |
| 383 | 386 | ||
| 384 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | 387 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, |
| 385 | timekeeper.mult); | 388 | timekeeper.mult); |
| 386 | 389 | ||
| 387 | write_sequnlock_irqrestore(&xtime_lock, flags); | 390 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| @@ -413,12 +416,13 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
| 413 | timekeeping_forward_now(); | 416 | timekeeping_forward_now(); |
| 414 | 417 | ||
| 415 | xtime = timespec_add(xtime, *ts); | 418 | xtime = timespec_add(xtime, *ts); |
| 416 | wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts); | 419 | timekeeper.wall_to_monotonic = |
| 420 | timespec_sub(timekeeper.wall_to_monotonic, *ts); | ||
| 417 | 421 | ||
| 418 | timekeeper.ntp_error = 0; | 422 | timekeeper.ntp_error = 0; |
| 419 | ntp_clear(); | 423 | ntp_clear(); |
| 420 | 424 | ||
| 421 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | 425 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, |
| 422 | timekeeper.mult); | 426 | timekeeper.mult); |
| 423 | 427 | ||
| 424 | write_sequnlock_irqrestore(&xtime_lock, flags); | 428 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| @@ -592,7 +596,7 @@ void __init timekeeping_init(void) | |||
| 592 | boot.tv_sec = xtime.tv_sec; | 596 | boot.tv_sec = xtime.tv_sec; |
| 593 | boot.tv_nsec = xtime.tv_nsec; | 597 | boot.tv_nsec = xtime.tv_nsec; |
| 594 | } | 598 | } |
| 595 | set_normalized_timespec(&wall_to_monotonic, | 599 | set_normalized_timespec(&timekeeper.wall_to_monotonic, |
| 596 | -boot.tv_sec, -boot.tv_nsec); | 600 | -boot.tv_sec, -boot.tv_nsec); |
| 597 | timekeeper.total_sleep_time.tv_sec = 0; | 601 | timekeeper.total_sleep_time.tv_sec = 0; |
| 598 | timekeeper.total_sleep_time.tv_nsec = 0; | 602 | timekeeper.total_sleep_time.tv_nsec = 0; |
| @@ -618,7 +622,8 @@ static void __timekeeping_inject_sleeptime(struct timespec *delta) | |||
| 618 | } | 622 | } |
| 619 | 623 | ||
| 620 | xtime = timespec_add(xtime, *delta); | 624 | xtime = timespec_add(xtime, *delta); |
| 621 | wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); | 625 | timekeeper.wall_to_monotonic = |
| 626 | timespec_sub(timekeeper.wall_to_monotonic, *delta); | ||
| 622 | timekeeper.total_sleep_time = timespec_add( | 627 | timekeeper.total_sleep_time = timespec_add( |
| 623 | timekeeper.total_sleep_time, *delta); | 628 | timekeeper.total_sleep_time, *delta); |
| 624 | } | 629 | } |
| @@ -651,7 +656,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta) | |||
| 651 | 656 | ||
| 652 | timekeeper.ntp_error = 0; | 657 | timekeeper.ntp_error = 0; |
| 653 | ntp_clear(); | 658 | ntp_clear(); |
| 654 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | 659 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, |
| 655 | timekeeper.mult); | 660 | timekeeper.mult); |
| 656 | 661 | ||
| 657 | write_sequnlock_irqrestore(&xtime_lock, flags); | 662 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| @@ -1060,7 +1065,7 @@ static void update_wall_time(void) | |||
| 1060 | } | 1065 | } |
| 1061 | 1066 | ||
| 1062 | /* check to see if there is a new clocksource to use */ | 1067 | /* check to see if there is a new clocksource to use */ |
| 1063 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | 1068 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, |
| 1064 | timekeeper.mult); | 1069 | timekeeper.mult); |
| 1065 | } | 1070 | } |
| 1066 | 1071 | ||
| @@ -1078,9 +1083,9 @@ static void update_wall_time(void) | |||
| 1078 | void getboottime(struct timespec *ts) | 1083 | void getboottime(struct timespec *ts) |
| 1079 | { | 1084 | { |
| 1080 | struct timespec boottime = { | 1085 | struct timespec boottime = { |
| 1081 | .tv_sec = wall_to_monotonic.tv_sec + | 1086 | .tv_sec = timekeeper.wall_to_monotonic.tv_sec + |
| 1082 | timekeeper.total_sleep_time.tv_sec, | 1087 | timekeeper.total_sleep_time.tv_sec, |
| 1083 | .tv_nsec = wall_to_monotonic.tv_nsec + | 1088 | .tv_nsec = timekeeper.wall_to_monotonic.tv_nsec + |
| 1084 | timekeeper.total_sleep_time.tv_nsec | 1089 | timekeeper.total_sleep_time.tv_nsec |
| 1085 | }; | 1090 | }; |
| 1086 | 1091 | ||
| @@ -1109,7 +1114,7 @@ void get_monotonic_boottime(struct timespec *ts) | |||
| 1109 | do { | 1114 | do { |
| 1110 | seq = read_seqbegin(&xtime_lock); | 1115 | seq = read_seqbegin(&xtime_lock); |
| 1111 | *ts = xtime; | 1116 | *ts = xtime; |
| 1112 | tomono = wall_to_monotonic; | 1117 | tomono = timekeeper.wall_to_monotonic; |
| 1113 | sleep = timekeeper.total_sleep_time; | 1118 | sleep = timekeeper.total_sleep_time; |
| 1114 | nsecs = timekeeping_get_ns(); | 1119 | nsecs = timekeeping_get_ns(); |
| 1115 | 1120 | ||
| @@ -1182,7 +1187,7 @@ struct timespec get_monotonic_coarse(void) | |||
| 1182 | seq = read_seqbegin(&xtime_lock); | 1187 | seq = read_seqbegin(&xtime_lock); |
| 1183 | 1188 | ||
| 1184 | now = xtime; | 1189 | now = xtime; |
| 1185 | mono = wall_to_monotonic; | 1190 | mono = timekeeper.wall_to_monotonic; |
| 1186 | } while (read_seqretry(&xtime_lock, seq)); | 1191 | } while (read_seqretry(&xtime_lock, seq)); |
| 1187 | 1192 | ||
| 1188 | set_normalized_timespec(&now, now.tv_sec + mono.tv_sec, | 1193 | set_normalized_timespec(&now, now.tv_sec + mono.tv_sec, |
| @@ -1217,7 +1222,7 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | |||
| 1217 | do { | 1222 | do { |
| 1218 | seq = read_seqbegin(&xtime_lock); | 1223 | seq = read_seqbegin(&xtime_lock); |
| 1219 | *xtim = xtime; | 1224 | *xtim = xtime; |
| 1220 | *wtom = wall_to_monotonic; | 1225 | *wtom = timekeeper.wall_to_monotonic; |
| 1221 | *sleep = timekeeper.total_sleep_time; | 1226 | *sleep = timekeeper.total_sleep_time; |
| 1222 | } while (read_seqretry(&xtime_lock, seq)); | 1227 | } while (read_seqretry(&xtime_lock, seq)); |
| 1223 | } | 1228 | } |
| @@ -1232,7 +1237,7 @@ ktime_t ktime_get_monotonic_offset(void) | |||
| 1232 | 1237 | ||
| 1233 | do { | 1238 | do { |
| 1234 | seq = read_seqbegin(&xtime_lock); | 1239 | seq = read_seqbegin(&xtime_lock); |
| 1235 | wtom = wall_to_monotonic; | 1240 | wtom = timekeeper.wall_to_monotonic; |
| 1236 | } while (read_seqretry(&xtime_lock, seq)); | 1241 | } while (read_seqretry(&xtime_lock, seq)); |
| 1237 | return timespec_to_ktime(wtom); | 1242 | return timespec_to_ktime(wtom); |
| 1238 | } | 1243 | } |
