diff options
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 57c4d33c9a9d..ca99e2454600 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 | { |
@@ -77,6 +76,14 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | |||
77 | } | 76 | } |
78 | }; | 77 | }; |
79 | 78 | ||
79 | static int hrtimer_clock_to_base_table[MAX_CLOCKS]; | ||
80 | |||
81 | static inline int hrtimer_clockid_to_base(clockid_t clock_id) | ||
82 | { | ||
83 | return hrtimer_clock_to_base_table[clock_id]; | ||
84 | } | ||
85 | |||
86 | |||
80 | /* | 87 | /* |
81 | * Get the coarse grained time at the softirq based on xtime and | 88 | * Get the coarse grained time at the softirq based on xtime and |
82 | * wall_to_monotonic. | 89 | * wall_to_monotonic. |
@@ -90,8 +97,8 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | |||
90 | 97 | ||
91 | xtim = timespec_to_ktime(xts); | 98 | xtim = timespec_to_ktime(xts); |
92 | tomono = timespec_to_ktime(tom); | 99 | tomono = timespec_to_ktime(tom); |
93 | base->clock_base[CLOCK_REALTIME].softirq_time = xtim; | 100 | base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; |
94 | base->clock_base[CLOCK_MONOTONIC].softirq_time = | 101 | base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = |
95 | ktime_add(xtim, tomono); | 102 | ktime_add(xtim, tomono); |
96 | } | 103 | } |
97 | 104 | ||
@@ -179,10 +186,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, | |||
179 | struct hrtimer_cpu_base *new_cpu_base; | 186 | struct hrtimer_cpu_base *new_cpu_base; |
180 | int this_cpu = smp_processor_id(); | 187 | int this_cpu = smp_processor_id(); |
181 | int cpu = hrtimer_get_target(this_cpu, pinned); | 188 | int cpu = hrtimer_get_target(this_cpu, pinned); |
189 | int basenum = hrtimer_clockid_to_base(base->index); | ||
182 | 190 | ||
183 | again: | 191 | again: |
184 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); | 192 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); |
185 | new_base = &new_cpu_base->clock_base[base->index]; | 193 | new_base = &new_cpu_base->clock_base[basenum]; |
186 | 194 | ||
187 | if (base != new_base) { | 195 | if (base != new_base) { |
188 | /* | 196 | /* |
@@ -618,7 +626,7 @@ static void retrigger_next_event(void *arg) | |||
618 | 626 | ||
619 | /* Adjust CLOCK_REALTIME offset */ | 627 | /* Adjust CLOCK_REALTIME offset */ |
620 | raw_spin_lock(&base->lock); | 628 | raw_spin_lock(&base->lock); |
621 | base->clock_base[CLOCK_REALTIME].offset = | 629 | base->clock_base[HRTIMER_BASE_REALTIME].offset = |
622 | timespec_to_ktime(realtime_offset); | 630 | timespec_to_ktime(realtime_offset); |
623 | 631 | ||
624 | hrtimer_force_reprogram(base, 0); | 632 | hrtimer_force_reprogram(base, 0); |
@@ -716,8 +724,8 @@ static int hrtimer_switch_to_hres(void) | |||
716 | return 0; | 724 | return 0; |
717 | } | 725 | } |
718 | base->hres_active = 1; | 726 | base->hres_active = 1; |
719 | base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES; | 727 | base->clock_base[HRTIMER_BASE_REALTIME].resolution = KTIME_HIGH_RES; |
720 | base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES; | 728 | base->clock_base[HRTIMER_BASE_MONOTONIC].resolution = KTIME_HIGH_RES; |
721 | 729 | ||
722 | tick_setup_sched_timer(); | 730 | tick_setup_sched_timer(); |
723 | 731 | ||
@@ -1112,6 +1120,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1112 | enum hrtimer_mode mode) | 1120 | enum hrtimer_mode mode) |
1113 | { | 1121 | { |
1114 | struct hrtimer_cpu_base *cpu_base; | 1122 | struct hrtimer_cpu_base *cpu_base; |
1123 | int base; | ||
1115 | 1124 | ||
1116 | memset(timer, 0, sizeof(struct hrtimer)); | 1125 | memset(timer, 0, sizeof(struct hrtimer)); |
1117 | 1126 | ||
@@ -1120,7 +1129,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1120 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) | 1129 | if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) |
1121 | clock_id = CLOCK_MONOTONIC; | 1130 | clock_id = CLOCK_MONOTONIC; |
1122 | 1131 | ||
1123 | timer->base = &cpu_base->clock_base[clock_id]; | 1132 | base = hrtimer_clockid_to_base(clock_id); |
1133 | timer->base = &cpu_base->clock_base[base]; | ||
1124 | hrtimer_init_timer_hres(timer); | 1134 | hrtimer_init_timer_hres(timer); |
1125 | timerqueue_init(&timer->node); | 1135 | timerqueue_init(&timer->node); |
1126 | 1136 | ||
@@ -1156,9 +1166,10 @@ EXPORT_SYMBOL_GPL(hrtimer_init); | |||
1156 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | 1166 | int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) |
1157 | { | 1167 | { |
1158 | struct hrtimer_cpu_base *cpu_base; | 1168 | struct hrtimer_cpu_base *cpu_base; |
1169 | int base = hrtimer_clockid_to_base(which_clock); | ||
1159 | 1170 | ||
1160 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); | 1171 | cpu_base = &__raw_get_cpu_var(hrtimer_bases); |
1161 | *tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution); | 1172 | *tp = ktime_to_timespec(cpu_base->clock_base[base].resolution); |
1162 | 1173 | ||
1163 | return 0; | 1174 | return 0; |
1164 | } | 1175 | } |
@@ -1705,6 +1716,9 @@ static struct notifier_block __cpuinitdata hrtimers_nb = { | |||
1705 | 1716 | ||
1706 | void __init hrtimers_init(void) | 1717 | void __init hrtimers_init(void) |
1707 | { | 1718 | { |
1719 | hrtimer_clock_to_base_table[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME; | ||
1720 | hrtimer_clock_to_base_table[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC; | ||
1721 | |||
1708 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, | 1722 | hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, |
1709 | (void *)(long)smp_processor_id()); | 1723 | (void *)(long)smp_processor_id()); |
1710 | register_cpu_notifier(&hrtimers_nb); | 1724 | register_cpu_notifier(&hrtimers_nb); |