diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/Kconfig | 58 | ||||
-rw-r--r-- | kernel/time/alarmtimer.c | 4 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 3 | ||||
-rw-r--r-- | kernel/time/ntp.c | 8 | ||||
-rw-r--r-- | kernel/time/tick-broadcast.c | 13 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 26 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 6 |
7 files changed, 91 insertions, 27 deletions
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index a20dc8a3c949..fd42bd452b75 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig | |||
@@ -2,6 +2,55 @@ | |||
2 | # Timer subsystem related configuration options | 2 | # Timer subsystem related configuration options |
3 | # | 3 | # |
4 | 4 | ||
5 | # Options selectable by arch Kconfig | ||
6 | |||
7 | # Watchdog function for clocksources to detect instabilities | ||
8 | config CLOCKSOURCE_WATCHDOG | ||
9 | bool | ||
10 | |||
11 | # Architecture has extra clocksource data | ||
12 | config ARCH_CLOCKSOURCE_DATA | ||
13 | bool | ||
14 | |||
15 | # Timekeeping vsyscall support | ||
16 | config GENERIC_TIME_VSYSCALL | ||
17 | bool | ||
18 | |||
19 | # ktime_t scalar 64bit nsec representation | ||
20 | config KTIME_SCALAR | ||
21 | bool | ||
22 | |||
23 | # Old style timekeeping | ||
24 | config ARCH_USES_GETTIMEOFFSET | ||
25 | bool | ||
26 | |||
27 | # The generic clock events infrastructure | ||
28 | config GENERIC_CLOCKEVENTS | ||
29 | bool | ||
30 | |||
31 | # Migration helper. Builds, but does not invoke | ||
32 | config GENERIC_CLOCKEVENTS_BUILD | ||
33 | bool | ||
34 | default y | ||
35 | depends on GENERIC_CLOCKEVENTS | ||
36 | |||
37 | # Clockevents broadcasting infrastructure | ||
38 | config GENERIC_CLOCKEVENTS_BROADCAST | ||
39 | bool | ||
40 | depends on GENERIC_CLOCKEVENTS | ||
41 | |||
42 | # Automatically adjust the min. reprogramming time for | ||
43 | # clock event device | ||
44 | config GENERIC_CLOCKEVENTS_MIN_ADJUST | ||
45 | bool | ||
46 | |||
47 | # Generic update of CMOS clock | ||
48 | config GENERIC_CMOS_UPDATE | ||
49 | bool | ||
50 | |||
51 | if GENERIC_CLOCKEVENTS | ||
52 | menu "Timers subsystem" | ||
53 | |||
5 | # Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is | 54 | # Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is |
6 | # only related to the tick functionality. Oneshot clockevent devices | 55 | # only related to the tick functionality. Oneshot clockevent devices |
7 | # are supported independ of this. | 56 | # are supported independ of this. |
@@ -26,10 +75,5 @@ config HIGH_RES_TIMERS | |||
26 | hardware is not capable then this option only increases | 75 | hardware is not capable then this option only increases |
27 | the size of the kernel image. | 76 | the size of the kernel image. |
28 | 77 | ||
29 | config GENERIC_CLOCKEVENTS_BUILD | 78 | endmenu |
30 | bool | 79 | endif |
31 | default y | ||
32 | depends on GENERIC_CLOCKEVENTS | ||
33 | |||
34 | config GENERIC_CLOCKEVENTS_MIN_ADJUST | ||
35 | bool | ||
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 8a538c55fc7b..aa27d391bfc8 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(rtcdev_lock); | |||
59 | * If one has not already been chosen, it checks to see if a | 59 | * If one has not already been chosen, it checks to see if a |
60 | * functional rtc device is available. | 60 | * functional rtc device is available. |
61 | */ | 61 | */ |
62 | static struct rtc_device *alarmtimer_get_rtcdev(void) | 62 | struct rtc_device *alarmtimer_get_rtcdev(void) |
63 | { | 63 | { |
64 | unsigned long flags; | 64 | unsigned long flags; |
65 | struct rtc_device *ret; | 65 | struct rtc_device *ret; |
@@ -115,7 +115,7 @@ static void alarmtimer_rtc_interface_remove(void) | |||
115 | class_interface_unregister(&alarmtimer_rtc_interface); | 115 | class_interface_unregister(&alarmtimer_rtc_interface); |
116 | } | 116 | } |
117 | #else | 117 | #else |
118 | static inline struct rtc_device *alarmtimer_get_rtcdev(void) | 118 | struct rtc_device *alarmtimer_get_rtcdev(void) |
119 | { | 119 | { |
120 | return NULL; | 120 | return NULL; |
121 | } | 121 | } |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 9cd928f7a7c6..7e1ce012a851 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -297,8 +297,7 @@ void clockevents_register_device(struct clock_event_device *dev) | |||
297 | } | 297 | } |
298 | EXPORT_SYMBOL_GPL(clockevents_register_device); | 298 | EXPORT_SYMBOL_GPL(clockevents_register_device); |
299 | 299 | ||
300 | static void clockevents_config(struct clock_event_device *dev, | 300 | void clockevents_config(struct clock_event_device *dev, u32 freq) |
301 | u32 freq) | ||
302 | { | 301 | { |
303 | u64 sec; | 302 | u64 sec; |
304 | 303 | ||
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index f03fd83b170b..70b33abcc7bb 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -412,6 +412,7 @@ int second_overflow(unsigned long secs) | |||
412 | if (secs % 86400 == 0) { | 412 | if (secs % 86400 == 0) { |
413 | leap = -1; | 413 | leap = -1; |
414 | time_state = TIME_OOP; | 414 | time_state = TIME_OOP; |
415 | time_tai++; | ||
415 | printk(KERN_NOTICE | 416 | printk(KERN_NOTICE |
416 | "Clock: inserting leap second 23:59:60 UTC\n"); | 417 | "Clock: inserting leap second 23:59:60 UTC\n"); |
417 | } | 418 | } |
@@ -426,7 +427,6 @@ int second_overflow(unsigned long secs) | |||
426 | } | 427 | } |
427 | break; | 428 | break; |
428 | case TIME_OOP: | 429 | case TIME_OOP: |
429 | time_tai++; | ||
430 | time_state = TIME_WAIT; | 430 | time_state = TIME_WAIT; |
431 | break; | 431 | break; |
432 | 432 | ||
@@ -473,8 +473,6 @@ int second_overflow(unsigned long secs) | |||
473 | << NTP_SCALE_SHIFT; | 473 | << NTP_SCALE_SHIFT; |
474 | time_adjust = 0; | 474 | time_adjust = 0; |
475 | 475 | ||
476 | |||
477 | |||
478 | out: | 476 | out: |
479 | spin_unlock_irqrestore(&ntp_lock, flags); | 477 | spin_unlock_irqrestore(&ntp_lock, flags); |
480 | 478 | ||
@@ -559,10 +557,10 @@ static inline void process_adj_status(struct timex *txc, struct timespec *ts) | |||
559 | /* only set allowed bits */ | 557 | /* only set allowed bits */ |
560 | time_status &= STA_RONLY; | 558 | time_status &= STA_RONLY; |
561 | time_status |= txc->status & ~STA_RONLY; | 559 | time_status |= txc->status & ~STA_RONLY; |
562 | |||
563 | } | 560 | } |
561 | |||
564 | /* | 562 | /* |
565 | * Called with the xtime lock held, so we can access and modify | 563 | * Called with ntp_lock held, so we can access and modify |
566 | * all the global NTP state: | 564 | * all the global NTP state: |
567 | */ | 565 | */ |
568 | static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) | 566 | static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index bf57abdc7bd0..f113755695e2 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -346,7 +346,8 @@ int tick_resume_broadcast(void) | |||
346 | tick_get_broadcast_mask()); | 346 | tick_get_broadcast_mask()); |
347 | break; | 347 | break; |
348 | case TICKDEV_MODE_ONESHOT: | 348 | case TICKDEV_MODE_ONESHOT: |
349 | broadcast = tick_resume_broadcast_oneshot(bc); | 349 | if (!cpumask_empty(tick_get_broadcast_mask())) |
350 | broadcast = tick_resume_broadcast_oneshot(bc); | ||
350 | break; | 351 | break; |
351 | } | 352 | } |
352 | } | 353 | } |
@@ -373,6 +374,9 @@ static int tick_broadcast_set_event(ktime_t expires, int force) | |||
373 | { | 374 | { |
374 | struct clock_event_device *bc = tick_broadcast_device.evtdev; | 375 | struct clock_event_device *bc = tick_broadcast_device.evtdev; |
375 | 376 | ||
377 | if (bc->mode != CLOCK_EVT_MODE_ONESHOT) | ||
378 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | ||
379 | |||
376 | return clockevents_program_event(bc, expires, force); | 380 | return clockevents_program_event(bc, expires, force); |
377 | } | 381 | } |
378 | 382 | ||
@@ -531,7 +535,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
531 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; | 535 | int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; |
532 | 536 | ||
533 | bc->event_handler = tick_handle_oneshot_broadcast; | 537 | bc->event_handler = tick_handle_oneshot_broadcast; |
534 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | ||
535 | 538 | ||
536 | /* Take the do_timer update */ | 539 | /* Take the do_timer update */ |
537 | tick_do_timer_cpu = cpu; | 540 | tick_do_timer_cpu = cpu; |
@@ -549,6 +552,7 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
549 | to_cpumask(tmpmask)); | 552 | to_cpumask(tmpmask)); |
550 | 553 | ||
551 | if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { | 554 | if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { |
555 | clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); | ||
552 | tick_broadcast_init_next_event(to_cpumask(tmpmask), | 556 | tick_broadcast_init_next_event(to_cpumask(tmpmask), |
553 | tick_next_period); | 557 | tick_next_period); |
554 | tick_broadcast_set_event(tick_next_period, 1); | 558 | tick_broadcast_set_event(tick_next_period, 1); |
@@ -577,15 +581,10 @@ void tick_broadcast_switch_to_oneshot(void) | |||
577 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); | 581 | raw_spin_lock_irqsave(&tick_broadcast_lock, flags); |
578 | 582 | ||
579 | tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; | 583 | tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; |
580 | |||
581 | if (cpumask_empty(tick_get_broadcast_mask())) | ||
582 | goto end; | ||
583 | |||
584 | bc = tick_broadcast_device.evtdev; | 584 | bc = tick_broadcast_device.evtdev; |
585 | if (bc) | 585 | if (bc) |
586 | tick_broadcast_setup_oneshot(bc); | 586 | tick_broadcast_setup_oneshot(bc); |
587 | 587 | ||
588 | end: | ||
589 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); | 588 | raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); |
590 | } | 589 | } |
591 | 590 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 6a3a5b9ff561..869997833928 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -274,6 +274,7 @@ EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); | |||
274 | static void tick_nohz_stop_sched_tick(struct tick_sched *ts) | 274 | static void tick_nohz_stop_sched_tick(struct tick_sched *ts) |
275 | { | 275 | { |
276 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; | 276 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; |
277 | unsigned long rcu_delta_jiffies; | ||
277 | ktime_t last_update, expires, now; | 278 | ktime_t last_update, expires, now; |
278 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | 279 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; |
279 | u64 time_delta; | 280 | u64 time_delta; |
@@ -322,7 +323,7 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts) | |||
322 | time_delta = timekeeping_max_deferment(); | 323 | time_delta = timekeeping_max_deferment(); |
323 | } while (read_seqretry(&xtime_lock, seq)); | 324 | } while (read_seqretry(&xtime_lock, seq)); |
324 | 325 | ||
325 | if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) || | 326 | if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) || |
326 | arch_needs_cpu(cpu)) { | 327 | arch_needs_cpu(cpu)) { |
327 | next_jiffies = last_jiffies + 1; | 328 | next_jiffies = last_jiffies + 1; |
328 | delta_jiffies = 1; | 329 | delta_jiffies = 1; |
@@ -330,6 +331,10 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts) | |||
330 | /* Get the next timer wheel timer */ | 331 | /* Get the next timer wheel timer */ |
331 | next_jiffies = get_next_timer_interrupt(last_jiffies); | 332 | next_jiffies = get_next_timer_interrupt(last_jiffies); |
332 | delta_jiffies = next_jiffies - last_jiffies; | 333 | delta_jiffies = next_jiffies - last_jiffies; |
334 | if (rcu_delta_jiffies < delta_jiffies) { | ||
335 | next_jiffies = last_jiffies + rcu_delta_jiffies; | ||
336 | delta_jiffies = rcu_delta_jiffies; | ||
337 | } | ||
333 | } | 338 | } |
334 | /* | 339 | /* |
335 | * Do not stop the tick, if we are only one off | 340 | * Do not stop the tick, if we are only one off |
@@ -576,6 +581,7 @@ void tick_nohz_idle_exit(void) | |||
576 | /* Update jiffies first */ | 581 | /* Update jiffies first */ |
577 | select_nohz_load_balancer(0); | 582 | select_nohz_load_balancer(0); |
578 | tick_do_update_jiffies64(now); | 583 | tick_do_update_jiffies64(now); |
584 | update_cpu_load_nohz(); | ||
579 | 585 | ||
580 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 586 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
581 | /* | 587 | /* |
@@ -814,6 +820,16 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
814 | return HRTIMER_RESTART; | 820 | return HRTIMER_RESTART; |
815 | } | 821 | } |
816 | 822 | ||
823 | static int sched_skew_tick; | ||
824 | |||
825 | static int __init skew_tick(char *str) | ||
826 | { | ||
827 | get_option(&str, &sched_skew_tick); | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | early_param("skew_tick", skew_tick); | ||
832 | |||
817 | /** | 833 | /** |
818 | * tick_setup_sched_timer - setup the tick emulation timer | 834 | * tick_setup_sched_timer - setup the tick emulation timer |
819 | */ | 835 | */ |
@@ -831,6 +847,14 @@ void tick_setup_sched_timer(void) | |||
831 | /* Get the next period (per cpu) */ | 847 | /* Get the next period (per cpu) */ |
832 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); | 848 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); |
833 | 849 | ||
850 | /* Offset the tick to avert xtime_lock contention. */ | ||
851 | if (sched_skew_tick) { | ||
852 | u64 offset = ktime_to_ns(tick_period) >> 1; | ||
853 | do_div(offset, num_possible_cpus()); | ||
854 | offset *= smp_processor_id(); | ||
855 | hrtimer_add_expires_ns(&ts->sched_timer, offset); | ||
856 | } | ||
857 | |||
834 | for (;;) { | 858 | for (;;) { |
835 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 859 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
836 | hrtimer_start_expires(&ts->sched_timer, | 860 | hrtimer_start_expires(&ts->sched_timer, |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index d66b21308f7c..6f46a00a1e8a 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -240,7 +240,6 @@ void getnstimeofday(struct timespec *ts) | |||
240 | 240 | ||
241 | timespec_add_ns(ts, nsecs); | 241 | timespec_add_ns(ts, nsecs); |
242 | } | 242 | } |
243 | |||
244 | EXPORT_SYMBOL(getnstimeofday); | 243 | EXPORT_SYMBOL(getnstimeofday); |
245 | 244 | ||
246 | ktime_t ktime_get(void) | 245 | ktime_t ktime_get(void) |
@@ -357,8 +356,8 @@ void do_gettimeofday(struct timeval *tv) | |||
357 | tv->tv_sec = now.tv_sec; | 356 | tv->tv_sec = now.tv_sec; |
358 | tv->tv_usec = now.tv_nsec/1000; | 357 | tv->tv_usec = now.tv_nsec/1000; |
359 | } | 358 | } |
360 | |||
361 | EXPORT_SYMBOL(do_gettimeofday); | 359 | EXPORT_SYMBOL(do_gettimeofday); |
360 | |||
362 | /** | 361 | /** |
363 | * do_settimeofday - Sets the time of day | 362 | * do_settimeofday - Sets the time of day |
364 | * @tv: pointer to the timespec variable containing the new time | 363 | * @tv: pointer to the timespec variable containing the new time |
@@ -392,7 +391,6 @@ int do_settimeofday(const struct timespec *tv) | |||
392 | 391 | ||
393 | return 0; | 392 | return 0; |
394 | } | 393 | } |
395 | |||
396 | EXPORT_SYMBOL(do_settimeofday); | 394 | EXPORT_SYMBOL(do_settimeofday); |
397 | 395 | ||
398 | 396 | ||
@@ -964,6 +962,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
964 | timekeeper.xtime.tv_sec++; | 962 | timekeeper.xtime.tv_sec++; |
965 | leap = second_overflow(timekeeper.xtime.tv_sec); | 963 | leap = second_overflow(timekeeper.xtime.tv_sec); |
966 | timekeeper.xtime.tv_sec += leap; | 964 | timekeeper.xtime.tv_sec += leap; |
965 | timekeeper.wall_to_monotonic.tv_sec -= leap; | ||
967 | } | 966 | } |
968 | 967 | ||
969 | /* Accumulate raw time */ | 968 | /* Accumulate raw time */ |
@@ -1079,6 +1078,7 @@ static void update_wall_time(void) | |||
1079 | timekeeper.xtime.tv_sec++; | 1078 | timekeeper.xtime.tv_sec++; |
1080 | leap = second_overflow(timekeeper.xtime.tv_sec); | 1079 | leap = second_overflow(timekeeper.xtime.tv_sec); |
1081 | timekeeper.xtime.tv_sec += leap; | 1080 | timekeeper.xtime.tv_sec += leap; |
1081 | timekeeper.wall_to_monotonic.tv_sec -= leap; | ||
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | timekeeping_update(false); | 1084 | timekeeping_update(false); |