diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2012-07-15 04:24:53 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2012-07-15 04:24:53 -0400 |
commit | e8b9dd7e2471b1274e3be719fcc385e0a710e46f (patch) | |
tree | 030d7ce20e8f8767d9423f78c102aba089eec372 /kernel/time | |
parent | 924412f66fd9d21212e560a93792b0b607d46c6e (diff) | |
parent | 6b1859dba01c7d512b72d77e3fd7da8354235189 (diff) |
Merge branch 'timers/urgent' into timers/core
Reason: Update to upstream changes to avoid further conflicts.
Fixup a trivial merge conflict in kernel/time/tick-sched.c
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/ntp.c | 8 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 9 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 63 |
3 files changed, 74 insertions, 6 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 70b33abcc7bb..b7fbadc5c973 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -409,7 +409,9 @@ int second_overflow(unsigned long secs) | |||
409 | time_state = TIME_DEL; | 409 | time_state = TIME_DEL; |
410 | break; | 410 | break; |
411 | case TIME_INS: | 411 | case TIME_INS: |
412 | if (secs % 86400 == 0) { | 412 | if (!(time_status & STA_INS)) |
413 | time_state = TIME_OK; | ||
414 | else if (secs % 86400 == 0) { | ||
413 | leap = -1; | 415 | leap = -1; |
414 | time_state = TIME_OOP; | 416 | time_state = TIME_OOP; |
415 | time_tai++; | 417 | time_tai++; |
@@ -418,7 +420,9 @@ int second_overflow(unsigned long secs) | |||
418 | } | 420 | } |
419 | break; | 421 | break; |
420 | case TIME_DEL: | 422 | case TIME_DEL: |
421 | if ((secs + 1) % 86400 == 0) { | 423 | if (!(time_status & STA_DEL)) |
424 | time_state = TIME_OK; | ||
425 | else if ((secs + 1) % 86400 == 0) { | ||
422 | leap = 1; | 426 | leap = 1; |
423 | time_tai--; | 427 | time_tai--; |
424 | time_state = TIME_WAIT; | 428 | time_state = TIME_WAIT; |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 60c9c60e9108..41be02250e08 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -276,10 +276,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
276 | { | 276 | { |
277 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; | 277 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; |
278 | ktime_t last_update, expires, ret = { .tv64 = 0 }; | 278 | ktime_t last_update, expires, ret = { .tv64 = 0 }; |
279 | unsigned long rcu_delta_jiffies; | ||
279 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | 280 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; |
280 | u64 time_delta; | 281 | u64 time_delta; |
281 | 282 | ||
282 | |||
283 | /* Read jiffies and the time when jiffies were updated last */ | 283 | /* Read jiffies and the time when jiffies were updated last */ |
284 | do { | 284 | do { |
285 | seq = read_seqbegin(&xtime_lock); | 285 | seq = read_seqbegin(&xtime_lock); |
@@ -288,7 +288,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
288 | time_delta = timekeeping_max_deferment(); | 288 | time_delta = timekeeping_max_deferment(); |
289 | } while (read_seqretry(&xtime_lock, seq)); | 289 | } while (read_seqretry(&xtime_lock, seq)); |
290 | 290 | ||
291 | if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) || | 291 | if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) || |
292 | arch_needs_cpu(cpu)) { | 292 | arch_needs_cpu(cpu)) { |
293 | next_jiffies = last_jiffies + 1; | 293 | next_jiffies = last_jiffies + 1; |
294 | delta_jiffies = 1; | 294 | delta_jiffies = 1; |
@@ -296,6 +296,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
296 | /* Get the next timer wheel timer */ | 296 | /* Get the next timer wheel timer */ |
297 | next_jiffies = get_next_timer_interrupt(last_jiffies); | 297 | next_jiffies = get_next_timer_interrupt(last_jiffies); |
298 | delta_jiffies = next_jiffies - last_jiffies; | 298 | delta_jiffies = next_jiffies - last_jiffies; |
299 | if (rcu_delta_jiffies < delta_jiffies) { | ||
300 | next_jiffies = last_jiffies + rcu_delta_jiffies; | ||
301 | delta_jiffies = rcu_delta_jiffies; | ||
302 | } | ||
299 | } | 303 | } |
300 | /* | 304 | /* |
301 | * Do not stop the tick, if we are only one off | 305 | * Do not stop the tick, if we are only one off |
@@ -369,6 +373,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
369 | */ | 373 | */ |
370 | if (!ts->tick_stopped) { | 374 | if (!ts->tick_stopped) { |
371 | select_nohz_load_balancer(1); | 375 | select_nohz_load_balancer(1); |
376 | calc_load_enter_idle(); | ||
372 | 377 | ||
373 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); | 378 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); |
374 | ts->tick_stopped = 1; | 379 | ts->tick_stopped = 1; |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 6f46a00a1e8a..269b1fe5f2ae 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 | ||
@@ -963,6 +984,8 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
963 | leap = second_overflow(timekeeper.xtime.tv_sec); | 984 | leap = second_overflow(timekeeper.xtime.tv_sec); |
964 | timekeeper.xtime.tv_sec += leap; | 985 | timekeeper.xtime.tv_sec += leap; |
965 | timekeeper.wall_to_monotonic.tv_sec -= leap; | 986 | timekeeper.wall_to_monotonic.tv_sec -= leap; |
987 | if (leap) | ||
988 | clock_was_set_delayed(); | ||
966 | } | 989 | } |
967 | 990 | ||
968 | /* Accumulate raw time */ | 991 | /* Accumulate raw time */ |
@@ -1079,6 +1102,8 @@ static void update_wall_time(void) | |||
1079 | leap = second_overflow(timekeeper.xtime.tv_sec); | 1102 | leap = second_overflow(timekeeper.xtime.tv_sec); |
1080 | timekeeper.xtime.tv_sec += leap; | 1103 | timekeeper.xtime.tv_sec += leap; |
1081 | timekeeper.wall_to_monotonic.tv_sec -= leap; | 1104 | timekeeper.wall_to_monotonic.tv_sec -= leap; |
1105 | if (leap) | ||
1106 | clock_was_set_delayed(); | ||
1082 | } | 1107 | } |
1083 | 1108 | ||
1084 | timekeeping_update(false); | 1109 | timekeeping_update(false); |
@@ -1246,6 +1271,40 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | |||
1246 | } while (read_seqretry(&timekeeper.lock, seq)); | 1271 | } while (read_seqretry(&timekeeper.lock, seq)); |
1247 | } | 1272 | } |
1248 | 1273 | ||
1274 | #ifdef CONFIG_HIGH_RES_TIMERS | ||
1275 | /** | ||
1276 | * ktime_get_update_offsets - hrtimer helper | ||
1277 | * @offs_real: pointer to storage for monotonic -> realtime offset | ||
1278 | * @offs_boot: pointer to storage for monotonic -> boottime offset | ||
1279 | * | ||
1280 | * Returns current monotonic time and updates the offsets | ||
1281 | * Called from hrtimer_interupt() or retrigger_next_event() | ||
1282 | */ | ||
1283 | ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) | ||
1284 | { | ||
1285 | ktime_t now; | ||
1286 | unsigned int seq; | ||
1287 | u64 secs, nsecs; | ||
1288 | |||
1289 | do { | ||
1290 | seq = read_seqbegin(&timekeeper.lock); | ||
1291 | |||
1292 | secs = timekeeper.xtime.tv_sec; | ||
1293 | nsecs = timekeeper.xtime.tv_nsec; | ||
1294 | nsecs += timekeeping_get_ns(); | ||
1295 | /* If arch requires, add in gettimeoffset() */ | ||
1296 | nsecs += arch_gettimeoffset(); | ||
1297 | |||
1298 | *offs_real = timekeeper.offs_real; | ||
1299 | *offs_boot = timekeeper.offs_boot; | ||
1300 | } while (read_seqretry(&timekeeper.lock, seq)); | ||
1301 | |||
1302 | now = ktime_add_ns(ktime_set(secs, 0), nsecs); | ||
1303 | now = ktime_sub(now, *offs_real); | ||
1304 | return now; | ||
1305 | } | ||
1306 | #endif | ||
1307 | |||
1249 | /** | 1308 | /** |
1250 | * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format | 1309 | * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format |
1251 | */ | 1310 | */ |