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); |
