diff options
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 0c8d7c04861..9017478c5d4 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -53,11 +53,10 @@ | |||
53 | /* | 53 | /* |
54 | * The timer bases: | 54 | * The timer bases: |
55 | * | 55 | * |
56 | * Note: If we want to add new timer bases, we have to skip the two | 56 | * There are more clockids then hrtimer bases. Thus, we index |
57 | * clock ids captured by the cpu-timers. We do this by holding empty | 57 | * into the timer bases by the hrtimer_base_type enum. When trying |
58 | * entries rather than doing math adjustment of the clock ids. | 58 | * to reach a base using a clockid, hrtimer_clockid_to_base() |
59 | * This ensures that we capture erroneous accesses to these clock ids | 59 | * is used to convert from clockid to the proper hrtimer_base_type. |
60 | * rather than moving them into the range of valid clock id's. | ||
61 | */ | 60 | */ |
62 | DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | 61 | DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = |
63 | { | 62 | { |
@@ -74,30 +73,39 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | |||
74 | .get_time = &ktime_get, | 73 | .get_time = &ktime_get, |
75 | .resolution = KTIME_LOW_RES, | 74 | .resolution = KTIME_LOW_RES, |
76 | }, | 75 | }, |
76 | { | ||
77 | .index = CLOCK_BOOTTIME, | ||
78 | .get_time = &ktime_get_boottime, | ||
79 | .resolution = KTIME_LOW_RES, | ||
80 | }, | ||
77 | } | 81 | } |
78 | }; | 82 | }; |
79 | 83 | ||
84 | static int hrtimer_clock_to_base_table[MAX_CLOCKS]; | ||
85 | |||
86 | static inline int hrtimer_clockid_to_base(clockid_t clock_id) | ||
87 | { | ||
88 | return hrtimer_clock_to_base_table[clock_id]; | ||
89 | } | ||
90 | |||
91 | |||
80 | /* | 92 | /* |
81 | * Get the coarse grained time at the softirq based on xtime and | 93 | * Get the coarse grained time at the softirq based on xtime and |
82 | * wall_to_monotonic. | 94 | * wall_to_monotonic. |
83 | */ | 95 | */ |
84 | static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | 96 | static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) |
85 | { | 97 | { |
86 | ktime_t xtim, tomono; | 98 | ktime_t xtim, mono, boot; |
87 | struct timespec xts, tom; | 99 | struct timespec xts, tom, slp; |
88 | unsigned long seq; | ||
89 | 100 | ||
90 | do { | 101 | get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); |
91 | seq = read_seqbegin(&xtime_lock); | ||
92 | xts = __current_kernel_time(); | ||
93 | tom = __get_wall_to_monotonic(); | ||
94 | } while (read_seqretry(&xtime_lock, seq)); | ||
95 | 102 | ||
96 | xtim = timespec_to_ktime(xts); | 103 | xtim = timespec_to_ktime(xts); |
97 | tomono = timespec_to_ktime(tom); | 104 | mono = ktime_add(xtim, timespec_to_ktime(tom)); |
98 | base->clock_base[CLOCK_REALTIME].softirq_time = xtim; | 105 | boot = ktime_add(mono, timespec_to_ktime(slp)); |
99 | base->clock_base[CLOCK_MONOTONIC].softirq_time = | 106 | base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; |
100 | ktime_add(xtim, tomono); | 107 | base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; |
108 | base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; | ||
101 | } | 109 | } |
102 | 110 | ||
103 | /* | 111 | /* |
@@ -184,10 +192,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, | |||
184 | struct hrtimer_cpu_base *new_cpu_base; | 192 | struct hrtimer_cpu_base *new_cpu_base; |
185 | int this_cpu = smp_processor_id(); | 193 | int this_cpu = smp_processor_id(); |
186 | int cpu = hrtimer_get_target(this_cpu, pinned); | 194 | int cpu = hrtimer_get_target(this_cpu, pinned); |
195 | int basenum = hrtimer_clockid_to_base(base->index); | ||
187 | 196 | ||
188 | again: | 197 | again: |
189 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); | 198 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); |
190 | new_base = &new_cpu_base->clock_base[base->index]; | 199 | new_base = &new_cpu_base->clock_base[basenum]; |
191 | 200 | ||
192 | if (base != new_base) { | 201 | if (base != new_base) { |
193 | /* | 202 | /* |
@@ -334,6 +343,11 @@ EXPORT_SYMBOL_GPL(ktime_add_safe); | |||
334 | 343 | ||
335 | static struct debug_obj_descr hrtimer_debug_descr; | 344 | static struct debug_obj_descr hrtimer_debug_descr; |
336 | 345 | ||
346 | static void *hrtimer_debug_hint(void *addr) | ||
347 | { | ||
348 | return ((struct hrtimer *) addr)->function; | ||
349 | } | ||
350 | |||
337 | /* | 351 | /* |
338 | * fixup_init is called when: | 352 | * fixup_init is called when: |
339 | * - an active object is initialized | 353 | * - an active object is initialized |
@@ -393,6 +407,7 @@ static int hrtimer_fixup_free(void *addr, enum debug_obj_state state) | |||
393 | 407 | ||
394 | static struct debug_obj_descr hrtimer_debug_descr = { | 408 | static struct debug_obj_descr hrtimer_debug_descr = { |
395 | .name = "hrtimer", | 409 | .name = "hrtimer", |
410 | .debug_hint = hrtimer_debug_hint, | ||
396 | .fixup_init = hrtimer_fixup_init, | 411 | .fixup_init = hrtimer_fixup_init, |
397 | .fixup_activate = hrtimer_fixup_activate, | 412 | .fixup_activate = hrtimer_fixup_activate, |
398 | .fixup_free = hrtimer_fixup_free, | 413 | .fixup_free = hrtimer_fixup_free, |
@@ -611,24 +626,23 @@ static int hrtimer_reprogram(struct hrtimer *timer, | |||
611 | static void retrigger_next_event(void *arg) | 626 | static void retrigger_next_event(void *arg) |
612 | { | 627 | { |
613 | struct hrtimer_cpu_base *base; | 628 | struct hrtimer_cpu_base *base; |
614 | struct timespec realtime_offset, wtm; | 629 | struct timespec realtime_offset, wtm, sleep; |
615 | unsigned long seq; | ||
616 | 630 | ||
617 | if (!hrtimer_hres_active()) | 631 | if (!hrtimer_hres_active()) |
618 | return; | 632 | return; |
619 | 633 | ||
620 | do { | 634 | get_xtime_and_monotonic_and_sleep_offset(&realtime_offset, &wtm, |
621 | seq = read_seqbegin(&xtime_lock); | 635 | &sleep); |
622 | wtm = __get_wall_to_monotonic(); | ||
623 | } while (read_seqretry(&xtime_lock, seq)); | ||
624 | set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); | 636 | set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec); |
625 | 637 | ||
626 | base = &__get_cpu_var(hrtimer_bases); | 638 | base = &__get_cpu_var(hrtimer_bases); |
627 | 639 | ||
628 | /* Adjust CLOCK_REALTIME offset */ | 640 | /* Adjust CLOCK_REALTIME offset */ |
629 | raw_spin_lock(&base->lock); | 641 | raw_spin_lock(&base->lock); |
630 | base->clock_base[CLOCK_REALTIME].offset = | 642 | base->clock_base[HRTIMER_BASE_REALTIME].offset = |
631 | timespec_to_ktime(realtime_offset); | 643 | timespec_to_ktime(realtime_offset); |
644 | base->clock_base[HRTIMER_BASE_BOOTTIME].offset = | ||
645 | timespec_to_ktime(sleep); | ||
632 | 646 | ||
633 | hrtimer_force_reprogram(base, 0); | 647 | hrtimer_force_reprogram(base, 0); |
634 | raw_spin_unlock(&base->lock); | 648 | raw_spin_unlock(&base->lock); |
@@ -673,14 +687,6 @@ static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) | |||
673 | } | 687 | } |
674 | 688 | ||
675 | /* | 689 | /* |
676 | * Initialize the high resolution related parts of a hrtimer | ||
677 | */ | ||
678 | static inline void hrtimer_init_timer_hres(struct hrtimer *timer) | ||
679 | { | ||
680 | } | ||
681 | |||
682 | |||
683 | /* | ||
684 | * When High resolution timers are active, try to reprogram. Note, that in case | 690 | * When High resolution timers are active, try to reprogram. Note, that in case |
685 | * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry | 691 | * the state has HRTIMER_STATE_CALLBACK set, no reprogramming and no expiry |
686 | * check happens. The timer gets enqueued into the rbtree. The reprogramming | 692 | * check happens. The timer gets enqueued into the rbtree. The reprogramming |
@@ -725,8 +731,9 @@ static int hrtimer_switch_to_hres(void) | |||
725 | return 0; | 731 | return 0; |
726 | } | 732 | } |
727 | base->hres_active = 1; | 733 | base->hres_active = 1; |
728 | base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES; | 734 | base->clock_base[HRTIMER_BASE_REALTIME].resolution = KTIME_HIGH_RES; |
729 | base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES; | 735 | base->clock_base[HRTIMER_BASE_MONOTONIC].resolution = KTIME_HIGH_RES; |
736 | base->clock_base[HRTIMER_BASE_BOOTTIME].resolution = KTIME_HIGH_RES; | ||
730 | 737 | ||
731 | tick_setup_sched_timer(); | 738 | tick_setup_sched_timer(); |
732 | 739 | ||
@@ -750,7 +757,6 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, | |||
750 | return 0; | 757 | return 0; |
751 | } | 758 | } |
752 | static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } | 759 | static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } |
753 | static inline void hrtimer_init_timer_hres(struct hrtimer *timer) { } | ||
754 | 760 | ||
755 | #endif /* CONFIG_HIGH_RES_TIMERS */ | 761 | #endif /* CONFIG_HIGH_RES_TIMERS */ |
756 | 762 | ||
@@ -1121,6 +1127,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1121 | enum hrtimer_mode mode) | 1127 | enum hrtimer_mode mode) |
1122 | { | 1128 | { |
1123 | struct hrtimer_cpu_base *cpu_base; | 1129 | struct hrtimer_cpu_base *cpu_base; |
1130 | int base; | ||
1124 | 1131 | ||
1125 | memset(timer, 0, sizeof(struct hrtimer)); | 1132 | memset(timer, 0, sizeof(struct hrtimer)); |
1126 | 1133 | ||
@@ -1129,8 +1136,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1129 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) | 1136 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) |
1130 | clock_id = CLOCK_MONOTONIC; | 1137 | clock_id = CLOCK_MONOTONIC; |
1131 | 1138 | ||
1132 | timer->base = &cpu_base->clock_base[clock_id]; | 1139 | base = hrtimer_clockid_to_base(clock_id); |
1133 | hrtimer_init_timer_hres(timer); | 1140 | timer->base = &cpu_base->clock_base[base]; |
1134 | timerqueue_init(&timer->node); | 1141 | timerqueue_init(&timer->node); |
1135 | 1142 | ||
1136 | #ifdef CONFIG_TIMER_STATS | 1143 | #ifdef CONFIG_TIMER_STATS |
@@ -1165,9 +1172,10 @@ EXPORT_SYMBOL_GPL(hrtimer_init); | |||
1165 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | 1172 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) |
1166 | { | 1173 | { |
1167 | struct hrtimer_cpu_base *cpu_base; | 1174 | struct hrtimer_cpu_base *cpu_base; |
1175 | int base = hrtimer_clockid_to_base(which_clock); | ||
1168 | 1176 | ||
1169 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); | 1177 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); |
1170 | *tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution); | 1178 | *tp = ktime_to_timespec(cpu_base->clock_base[base].resolution); |
1171 | 1179 | ||
1172 | return 0; | 1180 | return 0; |
1173 | } | 1181 | } |
@@ -1714,6 +1722,10 @@ static struct notifier_block __cpuinitdata hrtimers_nb = { | |||
1714 | 1722 | ||
1715 | void __init hrtimers_init(void) | 1723 | void __init hrtimers_init(void) |
1716 | { | 1724 | { |
1725 | hrtimer_clock_to_base_table[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME; | ||
1726 | hrtimer_clock_to_base_table[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC; | ||
1727 | hrtimer_clock_to_base_table[CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME; | ||
1728 | |||
1717 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, | 1729 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, |
1718 | (void *)(long)smp_processor_id()); | 1730 | (void *)(long)smp_processor_id()); |
1719 | register_cpu_notifier(&hrtimers_nb); | 1731 | register_cpu_notifier(&hrtimers_nb); |