diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-01-12 08:13:31 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-01-12 08:13:31 -0500 |
commit | d05d24a984f8e14086771a158083dbe6facb769e (patch) | |
tree | 0e897dc8cee3b884eef194b620c62d8a8fa8594c /kernel/time | |
parent | dba861461f88c12249ac78fb877866c04f99deb3 (diff) | |
parent | 38aef31ce7773624c8f09ff58c4c27b3b955faaf (diff) |
Merge branch 'fortglx/3.14/time' of git://git.linaro.org/people/john.stultz/linux into timers/core
Pull timekeeping updates from John Stultz.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/tick-common.c | 1 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 1 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 1 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 53 |
4 files changed, 29 insertions, 27 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 162b03ab0ad2..20b2fe37d105 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -85,6 +85,7 @@ static void tick_periodic(int cpu) | |||
85 | 85 | ||
86 | do_timer(1); | 86 | do_timer(1); |
87 | write_sequnlock(&jiffies_lock); | 87 | write_sequnlock(&jiffies_lock); |
88 | update_wall_time(); | ||
88 | } | 89 | } |
89 | 90 | ||
90 | update_process_times(user_mode(get_irq_regs())); | 91 | update_process_times(user_mode(get_irq_regs())); |
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index e2bced59b6dd..8329669b51ec 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -155,3 +155,4 @@ static inline int tick_device_is_functional(struct clock_event_device *dev) | |||
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | extern void do_timer(unsigned long ticks); | 157 | extern void do_timer(unsigned long ticks); |
158 | extern void update_wall_time(void); | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 52cee12b3302..0ddd020bbaf2 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -86,6 +86,7 @@ static void tick_do_update_jiffies64(ktime_t now) | |||
86 | tick_next_period = ktime_add(last_jiffies_update, tick_period); | 86 | tick_next_period = ktime_add(last_jiffies_update, tick_period); |
87 | } | 87 | } |
88 | write_sequnlock(&jiffies_lock); | 88 | write_sequnlock(&jiffies_lock); |
89 | update_wall_time(); | ||
89 | } | 90 | } |
90 | 91 | ||
91 | /* | 92 | /* |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 87b4f00284c9..0aa4ce81bc16 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -77,7 +77,7 @@ static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) | |||
77 | tk->wall_to_monotonic = wtm; | 77 | tk->wall_to_monotonic = wtm; |
78 | set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec); | 78 | set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec); |
79 | tk->offs_real = timespec_to_ktime(tmp); | 79 | tk->offs_real = timespec_to_ktime(tmp); |
80 | tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tk->tai_offset, 0)); | 80 | tk->offs_tai = ktime_add(tk->offs_real, ktime_set(tk->tai_offset, 0)); |
81 | } | 81 | } |
82 | 82 | ||
83 | static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) | 83 | static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) |
@@ -90,8 +90,9 @@ static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) | |||
90 | } | 90 | } |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * timekeeper_setup_internals - Set up internals to use clocksource clock. | 93 | * tk_setup_internals - Set up internals to use clocksource clock. |
94 | * | 94 | * |
95 | * @tk: The target timekeeper to setup. | ||
95 | * @clock: Pointer to clocksource. | 96 | * @clock: Pointer to clocksource. |
96 | * | 97 | * |
97 | * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment | 98 | * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment |
@@ -595,7 +596,7 @@ s32 timekeeping_get_tai_offset(void) | |||
595 | static void __timekeeping_set_tai_offset(struct timekeeper *tk, s32 tai_offset) | 596 | static void __timekeeping_set_tai_offset(struct timekeeper *tk, s32 tai_offset) |
596 | { | 597 | { |
597 | tk->tai_offset = tai_offset; | 598 | tk->tai_offset = tai_offset; |
598 | tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tai_offset, 0)); | 599 | tk->offs_tai = ktime_add(tk->offs_real, ktime_set(tai_offset, 0)); |
599 | } | 600 | } |
600 | 601 | ||
601 | /** | 602 | /** |
@@ -610,6 +611,7 @@ void timekeeping_set_tai_offset(s32 tai_offset) | |||
610 | raw_spin_lock_irqsave(&timekeeper_lock, flags); | 611 | raw_spin_lock_irqsave(&timekeeper_lock, flags); |
611 | write_seqcount_begin(&timekeeper_seq); | 612 | write_seqcount_begin(&timekeeper_seq); |
612 | __timekeeping_set_tai_offset(tk, tai_offset); | 613 | __timekeeping_set_tai_offset(tk, tai_offset); |
614 | timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); | ||
613 | write_seqcount_end(&timekeeper_seq); | 615 | write_seqcount_end(&timekeeper_seq); |
614 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 616 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
615 | clock_was_set(); | 617 | clock_was_set(); |
@@ -1023,6 +1025,8 @@ static int timekeeping_suspend(void) | |||
1023 | timekeeping_suspend_time = | 1025 | timekeeping_suspend_time = |
1024 | timespec_add(timekeeping_suspend_time, delta_delta); | 1026 | timespec_add(timekeeping_suspend_time, delta_delta); |
1025 | } | 1027 | } |
1028 | |||
1029 | timekeeping_update(tk, TK_MIRROR); | ||
1026 | write_seqcount_end(&timekeeper_seq); | 1030 | write_seqcount_end(&timekeeper_seq); |
1027 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 1031 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
1028 | 1032 | ||
@@ -1130,16 +1134,6 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) | |||
1130 | * we can adjust by 1. | 1134 | * we can adjust by 1. |
1131 | */ | 1135 | */ |
1132 | error >>= 2; | 1136 | error >>= 2; |
1133 | /* | ||
1134 | * XXX - In update_wall_time, we round up to the next | ||
1135 | * nanosecond, and store the amount rounded up into | ||
1136 | * the error. This causes the likely below to be unlikely. | ||
1137 | * | ||
1138 | * The proper fix is to avoid rounding up by using | ||
1139 | * the high precision tk->xtime_nsec instead of | ||
1140 | * xtime.tv_nsec everywhere. Fixing this will take some | ||
1141 | * time. | ||
1142 | */ | ||
1143 | if (likely(error <= interval)) | 1137 | if (likely(error <= interval)) |
1144 | adj = 1; | 1138 | adj = 1; |
1145 | else | 1139 | else |
@@ -1255,7 +1249,7 @@ out_adjust: | |||
1255 | static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk) | 1249 | static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk) |
1256 | { | 1250 | { |
1257 | u64 nsecps = (u64)NSEC_PER_SEC << tk->shift; | 1251 | u64 nsecps = (u64)NSEC_PER_SEC << tk->shift; |
1258 | unsigned int action = 0; | 1252 | unsigned int clock_set = 0; |
1259 | 1253 | ||
1260 | while (tk->xtime_nsec >= nsecps) { | 1254 | while (tk->xtime_nsec >= nsecps) { |
1261 | int leap; | 1255 | int leap; |
@@ -1277,11 +1271,10 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk) | |||
1277 | 1271 | ||
1278 | __timekeeping_set_tai_offset(tk, tk->tai_offset - leap); | 1272 | __timekeeping_set_tai_offset(tk, tk->tai_offset - leap); |
1279 | 1273 | ||
1280 | clock_was_set_delayed(); | 1274 | clock_set = TK_CLOCK_WAS_SET; |
1281 | action = TK_CLOCK_WAS_SET; | ||
1282 | } | 1275 | } |
1283 | } | 1276 | } |
1284 | return action; | 1277 | return clock_set; |
1285 | } | 1278 | } |
1286 | 1279 | ||
1287 | /** | 1280 | /** |
@@ -1294,7 +1287,8 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk) | |||
1294 | * Returns the unconsumed cycles. | 1287 | * Returns the unconsumed cycles. |
1295 | */ | 1288 | */ |
1296 | static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | 1289 | static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, |
1297 | u32 shift) | 1290 | u32 shift, |
1291 | unsigned int *clock_set) | ||
1298 | { | 1292 | { |
1299 | cycle_t interval = tk->cycle_interval << shift; | 1293 | cycle_t interval = tk->cycle_interval << shift; |
1300 | u64 raw_nsecs; | 1294 | u64 raw_nsecs; |
@@ -1308,7 +1302,7 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1308 | tk->cycle_last += interval; | 1302 | tk->cycle_last += interval; |
1309 | 1303 | ||
1310 | tk->xtime_nsec += tk->xtime_interval << shift; | 1304 | tk->xtime_nsec += tk->xtime_interval << shift; |
1311 | accumulate_nsecs_to_secs(tk); | 1305 | *clock_set |= accumulate_nsecs_to_secs(tk); |
1312 | 1306 | ||
1313 | /* Accumulate raw time */ | 1307 | /* Accumulate raw time */ |
1314 | raw_nsecs = (u64)tk->raw_interval << shift; | 1308 | raw_nsecs = (u64)tk->raw_interval << shift; |
@@ -1359,14 +1353,14 @@ static inline void old_vsyscall_fixup(struct timekeeper *tk) | |||
1359 | * update_wall_time - Uses the current clocksource to increment the wall time | 1353 | * update_wall_time - Uses the current clocksource to increment the wall time |
1360 | * | 1354 | * |
1361 | */ | 1355 | */ |
1362 | static void update_wall_time(void) | 1356 | void update_wall_time(void) |
1363 | { | 1357 | { |
1364 | struct clocksource *clock; | 1358 | struct clocksource *clock; |
1365 | struct timekeeper *real_tk = &timekeeper; | 1359 | struct timekeeper *real_tk = &timekeeper; |
1366 | struct timekeeper *tk = &shadow_timekeeper; | 1360 | struct timekeeper *tk = &shadow_timekeeper; |
1367 | cycle_t offset; | 1361 | cycle_t offset; |
1368 | int shift = 0, maxshift; | 1362 | int shift = 0, maxshift; |
1369 | unsigned int action; | 1363 | unsigned int clock_set = 0; |
1370 | unsigned long flags; | 1364 | unsigned long flags; |
1371 | 1365 | ||
1372 | raw_spin_lock_irqsave(&timekeeper_lock, flags); | 1366 | raw_spin_lock_irqsave(&timekeeper_lock, flags); |
@@ -1401,7 +1395,8 @@ static void update_wall_time(void) | |||
1401 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; | 1395 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; |
1402 | shift = min(shift, maxshift); | 1396 | shift = min(shift, maxshift); |
1403 | while (offset >= tk->cycle_interval) { | 1397 | while (offset >= tk->cycle_interval) { |
1404 | offset = logarithmic_accumulation(tk, offset, shift); | 1398 | offset = logarithmic_accumulation(tk, offset, shift, |
1399 | &clock_set); | ||
1405 | if (offset < tk->cycle_interval<<shift) | 1400 | if (offset < tk->cycle_interval<<shift) |
1406 | shift--; | 1401 | shift--; |
1407 | } | 1402 | } |
@@ -1419,7 +1414,7 @@ static void update_wall_time(void) | |||
1419 | * Finally, make sure that after the rounding | 1414 | * Finally, make sure that after the rounding |
1420 | * xtime_nsec isn't larger than NSEC_PER_SEC | 1415 | * xtime_nsec isn't larger than NSEC_PER_SEC |
1421 | */ | 1416 | */ |
1422 | action = accumulate_nsecs_to_secs(tk); | 1417 | clock_set |= accumulate_nsecs_to_secs(tk); |
1423 | 1418 | ||
1424 | write_seqcount_begin(&timekeeper_seq); | 1419 | write_seqcount_begin(&timekeeper_seq); |
1425 | /* Update clock->cycle_last with the new value */ | 1420 | /* Update clock->cycle_last with the new value */ |
@@ -1435,10 +1430,12 @@ static void update_wall_time(void) | |||
1435 | * updating. | 1430 | * updating. |
1436 | */ | 1431 | */ |
1437 | memcpy(real_tk, tk, sizeof(*tk)); | 1432 | memcpy(real_tk, tk, sizeof(*tk)); |
1438 | timekeeping_update(real_tk, action); | 1433 | timekeeping_update(real_tk, clock_set); |
1439 | write_seqcount_end(&timekeeper_seq); | 1434 | write_seqcount_end(&timekeeper_seq); |
1440 | out: | 1435 | out: |
1441 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 1436 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
1437 | if (clock_set) | ||
1438 | clock_was_set(); | ||
1442 | } | 1439 | } |
1443 | 1440 | ||
1444 | /** | 1441 | /** |
@@ -1583,7 +1580,6 @@ struct timespec get_monotonic_coarse(void) | |||
1583 | void do_timer(unsigned long ticks) | 1580 | void do_timer(unsigned long ticks) |
1584 | { | 1581 | { |
1585 | jiffies_64 += ticks; | 1582 | jiffies_64 += ticks; |
1586 | update_wall_time(); | ||
1587 | calc_global_load(ticks); | 1583 | calc_global_load(ticks); |
1588 | } | 1584 | } |
1589 | 1585 | ||
@@ -1698,12 +1694,14 @@ int do_adjtimex(struct timex *txc) | |||
1698 | 1694 | ||
1699 | if (tai != orig_tai) { | 1695 | if (tai != orig_tai) { |
1700 | __timekeeping_set_tai_offset(tk, tai); | 1696 | __timekeeping_set_tai_offset(tk, tai); |
1701 | update_pvclock_gtod(tk, true); | 1697 | timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); |
1702 | clock_was_set_delayed(); | ||
1703 | } | 1698 | } |
1704 | write_seqcount_end(&timekeeper_seq); | 1699 | write_seqcount_end(&timekeeper_seq); |
1705 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); | 1700 | raw_spin_unlock_irqrestore(&timekeeper_lock, flags); |
1706 | 1701 | ||
1702 | if (tai != orig_tai) | ||
1703 | clock_was_set(); | ||
1704 | |||
1707 | ntp_notify_cmos_timer(); | 1705 | ntp_notify_cmos_timer(); |
1708 | 1706 | ||
1709 | return ret; | 1707 | return ret; |
@@ -1739,4 +1737,5 @@ void xtime_update(unsigned long ticks) | |||
1739 | write_seqlock(&jiffies_lock); | 1737 | write_seqlock(&jiffies_lock); |
1740 | do_timer(ticks); | 1738 | do_timer(ticks); |
1741 | write_sequnlock(&jiffies_lock); | 1739 | write_sequnlock(&jiffies_lock); |
1740 | update_wall_time(); | ||
1742 | } | 1741 | } |