diff options
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 97 |
1 files changed, 33 insertions, 64 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 49da79ab8486..e5d98ce50f89 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -48,36 +48,7 @@ | |||
48 | 48 | ||
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
50 | 50 | ||
51 | /** | 51 | #include <trace/events/timer.h> |
52 | * ktime_get - get the monotonic time in ktime_t format | ||
53 | * | ||
54 | * returns the time in ktime_t format | ||
55 | */ | ||
56 | ktime_t ktime_get(void) | ||
57 | { | ||
58 | struct timespec now; | ||
59 | |||
60 | ktime_get_ts(&now); | ||
61 | |||
62 | return timespec_to_ktime(now); | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(ktime_get); | ||
65 | |||
66 | /** | ||
67 | * ktime_get_real - get the real (wall-) time in ktime_t format | ||
68 | * | ||
69 | * returns the time in ktime_t format | ||
70 | */ | ||
71 | ktime_t ktime_get_real(void) | ||
72 | { | ||
73 | struct timespec now; | ||
74 | |||
75 | getnstimeofday(&now); | ||
76 | |||
77 | return timespec_to_ktime(now); | ||
78 | } | ||
79 | |||
80 | EXPORT_SYMBOL_GPL(ktime_get_real); | ||
81 | 52 | ||
82 | /* | 53 | /* |
83 | * The timer bases: | 54 | * The timer bases: |
@@ -106,31 +77,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = | |||
106 | } | 77 | } |
107 | }; | 78 | }; |
108 | 79 | ||
109 | /** | ||
110 | * ktime_get_ts - get the monotonic clock in timespec format | ||
111 | * @ts: pointer to timespec variable | ||
112 | * | ||
113 | * The function calculates the monotonic clock from the realtime | ||
114 | * clock and the wall_to_monotonic offset and stores the result | ||
115 | * in normalized timespec format in the variable pointed to by @ts. | ||
116 | */ | ||
117 | void ktime_get_ts(struct timespec *ts) | ||
118 | { | ||
119 | struct timespec tomono; | ||
120 | unsigned long seq; | ||
121 | |||
122 | do { | ||
123 | seq = read_seqbegin(&xtime_lock); | ||
124 | getnstimeofday(ts); | ||
125 | tomono = wall_to_monotonic; | ||
126 | |||
127 | } while (read_seqretry(&xtime_lock, seq)); | ||
128 | |||
129 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | ||
130 | ts->tv_nsec + tomono.tv_nsec); | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(ktime_get_ts); | ||
133 | |||
134 | /* | 80 | /* |
135 | * Get the coarse grained time at the softirq based on xtime and | 81 | * Get the coarse grained time at the softirq based on xtime and |
136 | * wall_to_monotonic. | 82 | * wall_to_monotonic. |
@@ -485,6 +431,7 @@ void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id, | |||
485 | debug_object_init_on_stack(timer, &hrtimer_debug_descr); | 431 | debug_object_init_on_stack(timer, &hrtimer_debug_descr); |
486 | __hrtimer_init(timer, clock_id, mode); | 432 | __hrtimer_init(timer, clock_id, mode); |
487 | } | 433 | } |
434 | EXPORT_SYMBOL_GPL(hrtimer_init_on_stack); | ||
488 | 435 | ||
489 | void destroy_hrtimer_on_stack(struct hrtimer *timer) | 436 | void destroy_hrtimer_on_stack(struct hrtimer *timer) |
490 | { | 437 | { |
@@ -497,6 +444,26 @@ static inline void debug_hrtimer_activate(struct hrtimer *timer) { } | |||
497 | static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { } | 444 | static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { } |
498 | #endif | 445 | #endif |
499 | 446 | ||
447 | static inline void | ||
448 | debug_init(struct hrtimer *timer, clockid_t clockid, | ||
449 | enum hrtimer_mode mode) | ||
450 | { | ||
451 | debug_hrtimer_init(timer); | ||
452 | trace_hrtimer_init(timer, clockid, mode); | ||
453 | } | ||
454 | |||
455 | static inline void debug_activate(struct hrtimer *timer) | ||
456 | { | ||
457 | debug_hrtimer_activate(timer); | ||
458 | trace_hrtimer_start(timer); | ||
459 | } | ||
460 | |||
461 | static inline void debug_deactivate(struct hrtimer *timer) | ||
462 | { | ||
463 | debug_hrtimer_deactivate(timer); | ||
464 | trace_hrtimer_cancel(timer); | ||
465 | } | ||
466 | |||
500 | /* High resolution timer related functions */ | 467 | /* High resolution timer related functions */ |
501 | #ifdef CONFIG_HIGH_RES_TIMERS | 468 | #ifdef CONFIG_HIGH_RES_TIMERS |
502 | 469 | ||
@@ -853,7 +820,7 @@ static int enqueue_hrtimer(struct hrtimer *timer, | |||
853 | struct hrtimer *entry; | 820 | struct hrtimer *entry; |
854 | int leftmost = 1; | 821 | int leftmost = 1; |
855 | 822 | ||
856 | debug_hrtimer_activate(timer); | 823 | debug_activate(timer); |
857 | 824 | ||
858 | /* | 825 | /* |
859 | * Find the right place in the rbtree: | 826 | * Find the right place in the rbtree: |
@@ -939,7 +906,7 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base) | |||
939 | * reprogramming happens in the interrupt handler. This is a | 906 | * reprogramming happens in the interrupt handler. This is a |
940 | * rare case and less expensive than a smp call. | 907 | * rare case and less expensive than a smp call. |
941 | */ | 908 | */ |
942 | debug_hrtimer_deactivate(timer); | 909 | debug_deactivate(timer); |
943 | timer_stats_hrtimer_clear_start_info(timer); | 910 | timer_stats_hrtimer_clear_start_info(timer); |
944 | reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases); | 911 | reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases); |
945 | __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, | 912 | __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, |
@@ -1154,7 +1121,6 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1154 | clock_id = CLOCK_MONOTONIC; | 1121 | clock_id = CLOCK_MONOTONIC; |
1155 | 1122 | ||
1156 | timer->base = &cpu_base->clock_base[clock_id]; | 1123 | timer->base = &cpu_base->clock_base[clock_id]; |
1157 | INIT_LIST_HEAD(&timer->cb_entry); | ||
1158 | hrtimer_init_timer_hres(timer); | 1124 | hrtimer_init_timer_hres(timer); |
1159 | 1125 | ||
1160 | #ifdef CONFIG_TIMER_STATS | 1126 | #ifdef CONFIG_TIMER_STATS |
@@ -1173,7 +1139,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1173 | void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | 1139 | void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, |
1174 | enum hrtimer_mode mode) | 1140 | enum hrtimer_mode mode) |
1175 | { | 1141 | { |
1176 | debug_hrtimer_init(timer); | 1142 | debug_init(timer, clock_id, mode); |
1177 | __hrtimer_init(timer, clock_id, mode); | 1143 | __hrtimer_init(timer, clock_id, mode); |
1178 | } | 1144 | } |
1179 | EXPORT_SYMBOL_GPL(hrtimer_init); | 1145 | EXPORT_SYMBOL_GPL(hrtimer_init); |
@@ -1197,7 +1163,7 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
1197 | } | 1163 | } |
1198 | EXPORT_SYMBOL_GPL(hrtimer_get_res); | 1164 | EXPORT_SYMBOL_GPL(hrtimer_get_res); |
1199 | 1165 | ||
1200 | static void __run_hrtimer(struct hrtimer *timer) | 1166 | static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) |
1201 | { | 1167 | { |
1202 | struct hrtimer_clock_base *base = timer->base; | 1168 | struct hrtimer_clock_base *base = timer->base; |
1203 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; | 1169 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; |
@@ -1206,7 +1172,7 @@ static void __run_hrtimer(struct hrtimer *timer) | |||
1206 | 1172 | ||
1207 | WARN_ON(!irqs_disabled()); | 1173 | WARN_ON(!irqs_disabled()); |
1208 | 1174 | ||
1209 | debug_hrtimer_deactivate(timer); | 1175 | debug_deactivate(timer); |
1210 | __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0); | 1176 | __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0); |
1211 | timer_stats_account_hrtimer(timer); | 1177 | timer_stats_account_hrtimer(timer); |
1212 | fn = timer->function; | 1178 | fn = timer->function; |
@@ -1217,7 +1183,9 @@ static void __run_hrtimer(struct hrtimer *timer) | |||
1217 | * the timer base. | 1183 | * the timer base. |
1218 | */ | 1184 | */ |
1219 | spin_unlock(&cpu_base->lock); | 1185 | spin_unlock(&cpu_base->lock); |
1186 | trace_hrtimer_expire_entry(timer, now); | ||
1220 | restart = fn(timer); | 1187 | restart = fn(timer); |
1188 | trace_hrtimer_expire_exit(timer); | ||
1221 | spin_lock(&cpu_base->lock); | 1189 | spin_lock(&cpu_base->lock); |
1222 | 1190 | ||
1223 | /* | 1191 | /* |
@@ -1328,7 +1296,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) | |||
1328 | break; | 1296 | break; |
1329 | } | 1297 | } |
1330 | 1298 | ||
1331 | __run_hrtimer(timer); | 1299 | __run_hrtimer(timer, &basenow); |
1332 | } | 1300 | } |
1333 | base++; | 1301 | base++; |
1334 | } | 1302 | } |
@@ -1450,7 +1418,7 @@ void hrtimer_run_queues(void) | |||
1450 | hrtimer_get_expires_tv64(timer)) | 1418 | hrtimer_get_expires_tv64(timer)) |
1451 | break; | 1419 | break; |
1452 | 1420 | ||
1453 | __run_hrtimer(timer); | 1421 | __run_hrtimer(timer, &base->softirq_time); |
1454 | } | 1422 | } |
1455 | spin_unlock(&cpu_base->lock); | 1423 | spin_unlock(&cpu_base->lock); |
1456 | } | 1424 | } |
@@ -1477,6 +1445,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) | |||
1477 | sl->timer.function = hrtimer_wakeup; | 1445 | sl->timer.function = hrtimer_wakeup; |
1478 | sl->task = task; | 1446 | sl->task = task; |
1479 | } | 1447 | } |
1448 | EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); | ||
1480 | 1449 | ||
1481 | static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) | 1450 | static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) |
1482 | { | 1451 | { |
@@ -1626,7 +1595,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, | |||
1626 | while ((node = rb_first(&old_base->active))) { | 1595 | while ((node = rb_first(&old_base->active))) { |
1627 | timer = rb_entry(node, struct hrtimer, node); | 1596 | timer = rb_entry(node, struct hrtimer, node); |
1628 | BUG_ON(hrtimer_callback_running(timer)); | 1597 | BUG_ON(hrtimer_callback_running(timer)); |
1629 | debug_hrtimer_deactivate(timer); | 1598 | debug_deactivate(timer); |
1630 | 1599 | ||
1631 | /* | 1600 | /* |
1632 | * Mark it as STATE_MIGRATE not INACTIVE otherwise the | 1601 | * Mark it as STATE_MIGRATE not INACTIVE otherwise the |