aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/Kconfig58
-rw-r--r--kernel/time/alarmtimer.c4
-rw-r--r--kernel/time/clockevents.c3
-rw-r--r--kernel/time/ntp.c8
-rw-r--r--kernel/time/tick-broadcast.c13
-rw-r--r--kernel/time/tick-sched.c26
-rw-r--r--kernel/time/timekeeping.c6
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
8config CLOCKSOURCE_WATCHDOG
9 bool
10
11# Architecture has extra clocksource data
12config ARCH_CLOCKSOURCE_DATA
13 bool
14
15# Timekeeping vsyscall support
16config GENERIC_TIME_VSYSCALL
17 bool
18
19# ktime_t scalar 64bit nsec representation
20config KTIME_SCALAR
21 bool
22
23# Old style timekeeping
24config ARCH_USES_GETTIMEOFFSET
25 bool
26
27# The generic clock events infrastructure
28config GENERIC_CLOCKEVENTS
29 bool
30
31# Migration helper. Builds, but does not invoke
32config GENERIC_CLOCKEVENTS_BUILD
33 bool
34 default y
35 depends on GENERIC_CLOCKEVENTS
36
37# Clockevents broadcasting infrastructure
38config GENERIC_CLOCKEVENTS_BROADCAST
39 bool
40 depends on GENERIC_CLOCKEVENTS
41
42# Automatically adjust the min. reprogramming time for
43# clock event device
44config GENERIC_CLOCKEVENTS_MIN_ADJUST
45 bool
46
47# Generic update of CMOS clock
48config GENERIC_CMOS_UPDATE
49 bool
50
51if GENERIC_CLOCKEVENTS
52menu "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
29config GENERIC_CLOCKEVENTS_BUILD 78endmenu
30 bool 79endif
31 default y
32 depends on GENERIC_CLOCKEVENTS
33
34config 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 */
62static struct rtc_device *alarmtimer_get_rtcdev(void) 62struct 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
118static inline struct rtc_device *alarmtimer_get_rtcdev(void) 118struct 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}
298EXPORT_SYMBOL_GPL(clockevents_register_device); 298EXPORT_SYMBOL_GPL(clockevents_register_device);
299 299
300static void clockevents_config(struct clock_event_device *dev, 300void 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
478out: 476out:
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 */
568static inline void process_adjtimex_modes(struct timex *txc, struct timespec *ts) 566static 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
588end:
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);
274static void tick_nohz_stop_sched_tick(struct tick_sched *ts) 274static 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
823static int sched_skew_tick;
824
825static int __init skew_tick(char *str)
826{
827 get_option(&str, &sched_skew_tick);
828
829 return 0;
830}
831early_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
244EXPORT_SYMBOL(getnstimeofday); 243EXPORT_SYMBOL(getnstimeofday);
245 244
246ktime_t ktime_get(void) 245ktime_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
361EXPORT_SYMBOL(do_gettimeofday); 359EXPORT_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
396EXPORT_SYMBOL(do_settimeofday); 394EXPORT_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);