aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c40
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 */
62DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = 61DEFINE_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
79static int hrtimer_clock_to_base_table[MAX_CLOCKS];
80
81static 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
183again: 191again:
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);
1156int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) 1166int 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
1706void __init hrtimers_init(void) 1717void __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);