diff options
| author | John Stultz <john.stultz@linaro.org> | 2011-11-14 14:40:54 -0500 |
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2012-01-26 22:44:12 -0500 |
| commit | 8ff2cb92dd1afcf23e7b5287c43a900b16f40bad (patch) | |
| tree | 52c3e19533e4f44a491603f5842595c4e2630da0 /kernel | |
| parent | d9f7217aac6833cc634741f2f771a87fd1518fee (diff) | |
time: Move xtime into timekeeeper structure
In preparation for locking cleanups, move xtime into
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')
| -rw-r--r-- | kernel/time/timekeeping.c | 91 |
1 files changed, 47 insertions, 44 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 5655ca3a86d7..b30ffe6c6b06 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -48,6 +48,8 @@ struct timekeeper { | |||
| 48 | /* NTP adjusted clock multiplier */ | 48 | /* NTP adjusted clock multiplier */ |
| 49 | u32 mult; | 49 | u32 mult; |
| 50 | 50 | ||
| 51 | /* The current time */ | ||
| 52 | struct timespec xtime; | ||
| 51 | /* | 53 | /* |
| 52 | * wall_to_monotonic is what we need to add to xtime (or xtime corrected | 54 | * 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 | 55 | * for sub jiffie times) to get to monotonic time. Monotonic is pegged |
| @@ -161,10 +163,6 @@ static inline s64 timekeeping_get_ns_raw(void) | |||
| 161 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | 163 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); |
| 162 | 164 | ||
| 163 | 165 | ||
| 164 | /* | ||
| 165 | * The current time | ||
| 166 | */ | ||
| 167 | static struct timespec xtime __attribute__ ((aligned (16))); | ||
| 168 | 166 | ||
| 169 | /* | 167 | /* |
| 170 | * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. | 168 | * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. |
| @@ -177,10 +175,10 @@ int __read_mostly timekeeping_suspended; | |||
| 177 | /* must hold xtime_lock */ | 175 | /* must hold xtime_lock */ |
| 178 | void timekeeping_leap_insert(int leapsecond) | 176 | void timekeeping_leap_insert(int leapsecond) |
| 179 | { | 177 | { |
| 180 | xtime.tv_sec += leapsecond; | 178 | timekeeper.xtime.tv_sec += leapsecond; |
| 181 | timekeeper.wall_to_monotonic.tv_sec -= leapsecond; | 179 | timekeeper.wall_to_monotonic.tv_sec -= leapsecond; |
| 182 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, | 180 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 183 | timekeeper.mult); | 181 | timekeeper.clock, timekeeper.mult); |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | /** | 184 | /** |
| @@ -207,7 +205,7 @@ static void timekeeping_forward_now(void) | |||
| 207 | /* If arch requires, add in gettimeoffset() */ | 205 | /* If arch requires, add in gettimeoffset() */ |
| 208 | nsec += arch_gettimeoffset(); | 206 | nsec += arch_gettimeoffset(); |
| 209 | 207 | ||
| 210 | timespec_add_ns(&xtime, nsec); | 208 | timespec_add_ns(&timekeeper.xtime, nsec); |
| 211 | 209 | ||
| 212 | nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); | 210 | nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift); |
| 213 | timespec_add_ns(&raw_time, nsec); | 211 | timespec_add_ns(&raw_time, nsec); |
| @@ -229,7 +227,7 @@ void getnstimeofday(struct timespec *ts) | |||
| 229 | do { | 227 | do { |
| 230 | seq = read_seqbegin(&xtime_lock); | 228 | seq = read_seqbegin(&xtime_lock); |
| 231 | 229 | ||
| 232 | *ts = xtime; | 230 | *ts = timekeeper.xtime; |
| 233 | nsecs = timekeeping_get_ns(); | 231 | nsecs = timekeeping_get_ns(); |
| 234 | 232 | ||
| 235 | /* If arch requires, add in gettimeoffset() */ | 233 | /* If arch requires, add in gettimeoffset() */ |
| @@ -251,8 +249,10 @@ ktime_t ktime_get(void) | |||
| 251 | 249 | ||
| 252 | do { | 250 | do { |
| 253 | seq = read_seqbegin(&xtime_lock); | 251 | seq = read_seqbegin(&xtime_lock); |
| 254 | secs = xtime.tv_sec + timekeeper.wall_to_monotonic.tv_sec; | 252 | secs = timekeeper.xtime.tv_sec + |
| 255 | nsecs = xtime.tv_nsec + timekeeper.wall_to_monotonic.tv_nsec; | 253 | timekeeper.wall_to_monotonic.tv_sec; |
| 254 | nsecs = timekeeper.xtime.tv_nsec + | ||
| 255 | timekeeper.wall_to_monotonic.tv_nsec; | ||
| 256 | nsecs += timekeeping_get_ns(); | 256 | nsecs += timekeeping_get_ns(); |
| 257 | /* If arch requires, add in gettimeoffset() */ | 257 | /* If arch requires, add in gettimeoffset() */ |
| 258 | nsecs += arch_gettimeoffset(); | 258 | nsecs += arch_gettimeoffset(); |
| @@ -284,7 +284,7 @@ void ktime_get_ts(struct timespec *ts) | |||
| 284 | 284 | ||
| 285 | do { | 285 | do { |
| 286 | seq = read_seqbegin(&xtime_lock); | 286 | seq = read_seqbegin(&xtime_lock); |
| 287 | *ts = xtime; | 287 | *ts = timekeeper.xtime; |
| 288 | tomono = timekeeper.wall_to_monotonic; | 288 | tomono = timekeeper.wall_to_monotonic; |
| 289 | nsecs = timekeeping_get_ns(); | 289 | nsecs = timekeeping_get_ns(); |
| 290 | /* If arch requires, add in gettimeoffset() */ | 290 | /* If arch requires, add in gettimeoffset() */ |
| @@ -321,7 +321,7 @@ void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) | |||
| 321 | seq = read_seqbegin(&xtime_lock); | 321 | seq = read_seqbegin(&xtime_lock); |
| 322 | 322 | ||
| 323 | *ts_raw = raw_time; | 323 | *ts_raw = raw_time; |
| 324 | *ts_real = xtime; | 324 | *ts_real = timekeeper.xtime; |
| 325 | 325 | ||
| 326 | nsecs_raw = timekeeping_get_ns_raw(); | 326 | nsecs_raw = timekeeping_get_ns_raw(); |
| 327 | nsecs_real = timekeeping_get_ns(); | 327 | nsecs_real = timekeeping_get_ns(); |
| @@ -374,18 +374,18 @@ int do_settimeofday(const struct timespec *tv) | |||
| 374 | 374 | ||
| 375 | timekeeping_forward_now(); | 375 | timekeeping_forward_now(); |
| 376 | 376 | ||
| 377 | ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec; | 377 | ts_delta.tv_sec = tv->tv_sec - timekeeper.xtime.tv_sec; |
| 378 | ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec; | 378 | ts_delta.tv_nsec = tv->tv_nsec - timekeeper.xtime.tv_nsec; |
| 379 | timekeeper.wall_to_monotonic = | 379 | timekeeper.wall_to_monotonic = |
| 380 | timespec_sub(timekeeper.wall_to_monotonic, ts_delta); | 380 | timespec_sub(timekeeper.wall_to_monotonic, ts_delta); |
| 381 | 381 | ||
| 382 | xtime = *tv; | 382 | timekeeper.xtime = *tv; |
| 383 | 383 | ||
| 384 | timekeeper.ntp_error = 0; | 384 | timekeeper.ntp_error = 0; |
| 385 | ntp_clear(); | 385 | ntp_clear(); |
| 386 | 386 | ||
| 387 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, | 387 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 388 | timekeeper.mult); | 388 | timekeeper.clock, timekeeper.mult); |
| 389 | 389 | ||
| 390 | write_sequnlock_irqrestore(&xtime_lock, flags); | 390 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| 391 | 391 | ||
| @@ -415,15 +415,15 @@ int timekeeping_inject_offset(struct timespec *ts) | |||
| 415 | 415 | ||
| 416 | timekeeping_forward_now(); | 416 | timekeeping_forward_now(); |
| 417 | 417 | ||
| 418 | xtime = timespec_add(xtime, *ts); | 418 | timekeeper.xtime = timespec_add(timekeeper.xtime, *ts); |
| 419 | timekeeper.wall_to_monotonic = | 419 | timekeeper.wall_to_monotonic = |
| 420 | timespec_sub(timekeeper.wall_to_monotonic, *ts); | 420 | timespec_sub(timekeeper.wall_to_monotonic, *ts); |
| 421 | 421 | ||
| 422 | timekeeper.ntp_error = 0; | 422 | timekeeper.ntp_error = 0; |
| 423 | ntp_clear(); | 423 | ntp_clear(); |
| 424 | 424 | ||
| 425 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, | 425 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 426 | timekeeper.mult); | 426 | timekeeper.clock, timekeeper.mult); |
| 427 | 427 | ||
| 428 | write_sequnlock_irqrestore(&xtime_lock, flags); | 428 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| 429 | 429 | ||
| @@ -588,13 +588,13 @@ void __init timekeeping_init(void) | |||
| 588 | clock->enable(clock); | 588 | clock->enable(clock); |
| 589 | timekeeper_setup_internals(clock); | 589 | timekeeper_setup_internals(clock); |
| 590 | 590 | ||
| 591 | xtime.tv_sec = now.tv_sec; | 591 | timekeeper.xtime.tv_sec = now.tv_sec; |
| 592 | xtime.tv_nsec = now.tv_nsec; | 592 | timekeeper.xtime.tv_nsec = now.tv_nsec; |
| 593 | raw_time.tv_sec = 0; | 593 | raw_time.tv_sec = 0; |
| 594 | raw_time.tv_nsec = 0; | 594 | raw_time.tv_nsec = 0; |
| 595 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) { | 595 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) { |
| 596 | boot.tv_sec = xtime.tv_sec; | 596 | boot.tv_sec = timekeeper.xtime.tv_sec; |
| 597 | boot.tv_nsec = xtime.tv_nsec; | 597 | boot.tv_nsec = timekeeper.xtime.tv_nsec; |
| 598 | } | 598 | } |
| 599 | set_normalized_timespec(&timekeeper.wall_to_monotonic, | 599 | set_normalized_timespec(&timekeeper.wall_to_monotonic, |
| 600 | -boot.tv_sec, -boot.tv_nsec); | 600 | -boot.tv_sec, -boot.tv_nsec); |
| @@ -621,7 +621,7 @@ static void __timekeeping_inject_sleeptime(struct timespec *delta) | |||
| 621 | return; | 621 | return; |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | xtime = timespec_add(xtime, *delta); | 624 | timekeeper.xtime = timespec_add(timekeeper.xtime, *delta); |
| 625 | timekeeper.wall_to_monotonic = | 625 | timekeeper.wall_to_monotonic = |
| 626 | timespec_sub(timekeeper.wall_to_monotonic, *delta); | 626 | timespec_sub(timekeeper.wall_to_monotonic, *delta); |
| 627 | timekeeper.total_sleep_time = timespec_add( | 627 | timekeeper.total_sleep_time = timespec_add( |
| @@ -656,8 +656,8 @@ void timekeeping_inject_sleeptime(struct timespec *delta) | |||
| 656 | 656 | ||
| 657 | timekeeper.ntp_error = 0; | 657 | timekeeper.ntp_error = 0; |
| 658 | ntp_clear(); | 658 | ntp_clear(); |
| 659 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, | 659 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 660 | timekeeper.mult); | 660 | timekeeper.clock, timekeeper.mult); |
| 661 | 661 | ||
| 662 | write_sequnlock_irqrestore(&xtime_lock, flags); | 662 | write_sequnlock_irqrestore(&xtime_lock, flags); |
| 663 | 663 | ||
| @@ -720,7 +720,7 @@ static int timekeeping_suspend(void) | |||
| 720 | * try to compensate so the difference in system time | 720 | * try to compensate so the difference in system time |
| 721 | * and persistent_clock time stays close to constant. | 721 | * and persistent_clock time stays close to constant. |
| 722 | */ | 722 | */ |
| 723 | delta = timespec_sub(xtime, timekeeping_suspend_time); | 723 | delta = timespec_sub(timekeeper.xtime, timekeeping_suspend_time); |
| 724 | delta_delta = timespec_sub(delta, old_delta); | 724 | delta_delta = timespec_sub(delta, old_delta); |
| 725 | if (abs(delta_delta.tv_sec) >= 2) { | 725 | if (abs(delta_delta.tv_sec) >= 2) { |
| 726 | /* | 726 | /* |
| @@ -952,7 +952,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
| 952 | timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; | 952 | timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; |
| 953 | while (timekeeper.xtime_nsec >= nsecps) { | 953 | while (timekeeper.xtime_nsec >= nsecps) { |
| 954 | timekeeper.xtime_nsec -= nsecps; | 954 | timekeeper.xtime_nsec -= nsecps; |
| 955 | xtime.tv_sec++; | 955 | timekeeper.xtime.tv_sec++; |
| 956 | second_overflow(); | 956 | second_overflow(); |
| 957 | } | 957 | } |
| 958 | 958 | ||
| @@ -998,7 +998,8 @@ static void update_wall_time(void) | |||
| 998 | #else | 998 | #else |
| 999 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | 999 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; |
| 1000 | #endif | 1000 | #endif |
| 1001 | timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift; | 1001 | timekeeper.xtime_nsec = (s64)timekeeper.xtime.tv_nsec << |
| 1002 | timekeeper.shift; | ||
| 1002 | 1003 | ||
| 1003 | /* | 1004 | /* |
| 1004 | * With NO_HZ we may have to accumulate many cycle_intervals | 1005 | * With NO_HZ we may have to accumulate many cycle_intervals |
| @@ -1049,8 +1050,10 @@ static void update_wall_time(void) | |||
| 1049 | * Store full nanoseconds into xtime after rounding it up and | 1050 | * Store full nanoseconds into xtime after rounding it up and |
| 1050 | * add the remainder to the error difference. | 1051 | * add the remainder to the error difference. |
| 1051 | */ | 1052 | */ |
| 1052 | xtime.tv_nsec = ((s64) timekeeper.xtime_nsec >> timekeeper.shift) + 1; | 1053 | timekeeper.xtime.tv_nsec = ((s64)timekeeper.xtime_nsec >> |
| 1053 | timekeeper.xtime_nsec -= (s64) xtime.tv_nsec << timekeeper.shift; | 1054 | timekeeper.shift) + 1; |
| 1055 | timekeeper.xtime_nsec -= (s64)timekeeper.xtime.tv_nsec << | ||
| 1056 | timekeeper.shift; | ||
| 1054 | timekeeper.ntp_error += timekeeper.xtime_nsec << | 1057 | timekeeper.ntp_error += timekeeper.xtime_nsec << |
| 1055 | timekeeper.ntp_error_shift; | 1058 | timekeeper.ntp_error_shift; |
| 1056 | 1059 | ||
| @@ -1058,15 +1061,15 @@ static void update_wall_time(void) | |||
| 1058 | * Finally, make sure that after the rounding | 1061 | * Finally, make sure that after the rounding |
| 1059 | * xtime.tv_nsec isn't larger then NSEC_PER_SEC | 1062 | * xtime.tv_nsec isn't larger then NSEC_PER_SEC |
| 1060 | */ | 1063 | */ |
| 1061 | if (unlikely(xtime.tv_nsec >= NSEC_PER_SEC)) { | 1064 | if (unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC)) { |
| 1062 | xtime.tv_nsec -= NSEC_PER_SEC; | 1065 | timekeeper.xtime.tv_nsec -= NSEC_PER_SEC; |
| 1063 | xtime.tv_sec++; | 1066 | timekeeper.xtime.tv_sec++; |
| 1064 | second_overflow(); | 1067 | second_overflow(); |
| 1065 | } | 1068 | } |
| 1066 | 1069 | ||
| 1067 | /* check to see if there is a new clocksource to use */ | 1070 | /* check to see if there is a new clocksource to use */ |
| 1068 | update_vsyscall(&xtime, &timekeeper.wall_to_monotonic, timekeeper.clock, | 1071 | update_vsyscall(&timekeeper.xtime, &timekeeper.wall_to_monotonic, |
| 1069 | timekeeper.mult); | 1072 | timekeeper.clock, timekeeper.mult); |
| 1070 | } | 1073 | } |
| 1071 | 1074 | ||
| 1072 | /** | 1075 | /** |
| @@ -1113,7 +1116,7 @@ void get_monotonic_boottime(struct timespec *ts) | |||
| 1113 | 1116 | ||
| 1114 | do { | 1117 | do { |
| 1115 | seq = read_seqbegin(&xtime_lock); | 1118 | seq = read_seqbegin(&xtime_lock); |
| 1116 | *ts = xtime; | 1119 | *ts = timekeeper.xtime; |
| 1117 | tomono = timekeeper.wall_to_monotonic; | 1120 | tomono = timekeeper.wall_to_monotonic; |
| 1118 | sleep = timekeeper.total_sleep_time; | 1121 | sleep = timekeeper.total_sleep_time; |
| 1119 | nsecs = timekeeping_get_ns(); | 1122 | nsecs = timekeeping_get_ns(); |
| @@ -1154,13 +1157,13 @@ EXPORT_SYMBOL_GPL(monotonic_to_bootbased); | |||
| 1154 | 1157 | ||
| 1155 | unsigned long get_seconds(void) | 1158 | unsigned long get_seconds(void) |
| 1156 | { | 1159 | { |
| 1157 | return xtime.tv_sec; | 1160 | return timekeeper.xtime.tv_sec; |
| 1158 | } | 1161 | } |
| 1159 | EXPORT_SYMBOL(get_seconds); | 1162 | EXPORT_SYMBOL(get_seconds); |
| 1160 | 1163 | ||
| 1161 | struct timespec __current_kernel_time(void) | 1164 | struct timespec __current_kernel_time(void) |
| 1162 | { | 1165 | { |
| 1163 | return xtime; | 1166 | return timekeeper.xtime; |
| 1164 | } | 1167 | } |
| 1165 | 1168 | ||
| 1166 | struct timespec current_kernel_time(void) | 1169 | struct timespec current_kernel_time(void) |
| @@ -1171,7 +1174,7 @@ struct timespec current_kernel_time(void) | |||
| 1171 | do { | 1174 | do { |
| 1172 | seq = read_seqbegin(&xtime_lock); | 1175 | seq = read_seqbegin(&xtime_lock); |
| 1173 | 1176 | ||
| 1174 | now = xtime; | 1177 | now = timekeeper.xtime; |
| 1175 | } while (read_seqretry(&xtime_lock, seq)); | 1178 | } while (read_seqretry(&xtime_lock, seq)); |
| 1176 | 1179 | ||
| 1177 | return now; | 1180 | return now; |
| @@ -1186,7 +1189,7 @@ struct timespec get_monotonic_coarse(void) | |||
| 1186 | do { | 1189 | do { |
| 1187 | seq = read_seqbegin(&xtime_lock); | 1190 | seq = read_seqbegin(&xtime_lock); |
| 1188 | 1191 | ||
| 1189 | now = xtime; | 1192 | now = timekeeper.xtime; |
| 1190 | mono = timekeeper.wall_to_monotonic; | 1193 | mono = timekeeper.wall_to_monotonic; |
| 1191 | } while (read_seqretry(&xtime_lock, seq)); | 1194 | } while (read_seqretry(&xtime_lock, seq)); |
| 1192 | 1195 | ||
| @@ -1221,7 +1224,7 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | |||
| 1221 | 1224 | ||
| 1222 | do { | 1225 | do { |
| 1223 | seq = read_seqbegin(&xtime_lock); | 1226 | seq = read_seqbegin(&xtime_lock); |
| 1224 | *xtim = xtime; | 1227 | *xtim = timekeeper.xtime; |
| 1225 | *wtom = timekeeper.wall_to_monotonic; | 1228 | *wtom = timekeeper.wall_to_monotonic; |
| 1226 | *sleep = timekeeper.total_sleep_time; | 1229 | *sleep = timekeeper.total_sleep_time; |
| 1227 | } while (read_seqretry(&xtime_lock, seq)); | 1230 | } while (read_seqretry(&xtime_lock, seq)); |
