|
@@ -53,11 +53,10 @@
|
|
|
/*
|
|
|
* The timer bases:
|
|
|
*
|
|
|
- * Note: If we want to add new timer bases, we have to skip the two
|
|
|
- * clock ids captured by the cpu-timers. We do this by holding empty
|
|
|
- * entries rather than doing math adjustment of the clock ids.
|
|
|
- * This ensures that we capture erroneous accesses to these clock ids
|
|
|
- * rather than moving them into the range of valid clock id's.
|
|
|
+ * There are more clockids then hrtimer bases. Thus, we index
|
|
|
+ * into the timer bases by the hrtimer_base_type enum. When trying
|
|
|
+ * to reach a base using a clockid, hrtimer_clockid_to_base()
|
|
|
+ * is used to convert from clockid to the proper hrtimer_base_type.
|
|
|
*/
|
|
|
DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
|
|
|
{
|
|
@@ -77,6 +76,14 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+static int hrtimer_clock_to_base_table[MAX_CLOCKS];
|
|
|
+
|
|
|
+static inline int hrtimer_clockid_to_base(clockid_t clock_id)
|
|
|
+{
|
|
|
+ return hrtimer_clock_to_base_table[clock_id];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/*
|
|
|
* Get the coarse grained time at the softirq based on xtime and
|
|
|
* wall_to_monotonic.
|
|
@@ -90,8 +97,8 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
|
|
|
|
|
|
xtim = timespec_to_ktime(xts);
|
|
|
tomono = timespec_to_ktime(tom);
|
|
|
- base->clock_base[CLOCK_REALTIME].softirq_time = xtim;
|
|
|
- base->clock_base[CLOCK_MONOTONIC].softirq_time =
|
|
|
+ base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim;
|
|
|
+ base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time =
|
|
|
ktime_add(xtim, tomono);
|
|
|
}
|
|
|
|
|
@@ -179,10 +186,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
|
|
|
struct hrtimer_cpu_base *new_cpu_base;
|
|
|
int this_cpu = smp_processor_id();
|
|
|
int cpu = hrtimer_get_target(this_cpu, pinned);
|
|
|
+ int basenum = hrtimer_clockid_to_base(base->index);
|
|
|
|
|
|
again:
|
|
|
new_cpu_base = &per_cpu(hrtimer_bases, cpu);
|
|
|
- new_base = &new_cpu_base->clock_base[base->index];
|
|
|
+ new_base = &new_cpu_base->clock_base[basenum];
|
|
|
|
|
|
if (base != new_base) {
|
|
|
/*
|
|
@@ -618,7 +626,7 @@ static void retrigger_next_event(void *arg)
|
|
|
|
|
|
/* Adjust CLOCK_REALTIME offset */
|
|
|
raw_spin_lock(&base->lock);
|
|
|
- base->clock_base[CLOCK_REALTIME].offset =
|
|
|
+ base->clock_base[HRTIMER_BASE_REALTIME].offset =
|
|
|
timespec_to_ktime(realtime_offset);
|
|
|
|
|
|
hrtimer_force_reprogram(base, 0);
|
|
@@ -716,8 +724,8 @@ static int hrtimer_switch_to_hres(void)
|
|
|
return 0;
|
|
|
}
|
|
|
base->hres_active = 1;
|
|
|
- base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES;
|
|
|
- base->clock_base[CLOCK_MONOTONIC].resolution = KTIME_HIGH_RES;
|
|
|
+ base->clock_base[HRTIMER_BASE_REALTIME].resolution = KTIME_HIGH_RES;
|
|
|
+ base->clock_base[HRTIMER_BASE_MONOTONIC].resolution = KTIME_HIGH_RES;
|
|
|
|
|
|
tick_setup_sched_timer();
|
|
|
|
|
@@ -1112,6 +1120,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
|
|
|
enum hrtimer_mode mode)
|
|
|
{
|
|
|
struct hrtimer_cpu_base *cpu_base;
|
|
|
+ int base;
|
|
|
|
|
|
memset(timer, 0, sizeof(struct hrtimer));
|
|
|
|
|
@@ -1120,7 +1129,8 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
|
|
|
if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS)
|
|
|
clock_id = CLOCK_MONOTONIC;
|
|
|
|
|
|
- timer->base = &cpu_base->clock_base[clock_id];
|
|
|
+ base = hrtimer_clockid_to_base(clock_id);
|
|
|
+ timer->base = &cpu_base->clock_base[base];
|
|
|
hrtimer_init_timer_hres(timer);
|
|
|
timerqueue_init(&timer->node);
|
|
|
|
|
@@ -1156,9 +1166,10 @@ EXPORT_SYMBOL_GPL(hrtimer_init);
|
|
|
int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
|
|
|
{
|
|
|
struct hrtimer_cpu_base *cpu_base;
|
|
|
+ int base = hrtimer_clockid_to_base(which_clock);
|
|
|
|
|
|
cpu_base = &__raw_get_cpu_var(hrtimer_bases);
|
|
|
- *tp = ktime_to_timespec(cpu_base->clock_base[which_clock].resolution);
|
|
|
+ *tp = ktime_to_timespec(cpu_base->clock_base[base].resolution);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1705,6 +1716,9 @@ static struct notifier_block __cpuinitdata hrtimers_nb = {
|
|
|
|
|
|
void __init hrtimers_init(void)
|
|
|
{
|
|
|
+ hrtimer_clock_to_base_table[CLOCK_REALTIME] = HRTIMER_BASE_REALTIME;
|
|
|
+ hrtimer_clock_to_base_table[CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC;
|
|
|
+
|
|
|
hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
|
|
|
(void *)(long)smp_processor_id());
|
|
|
register_cpu_notifier(&hrtimers_nb);
|