diff options
author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2009-08-09 22:51:23 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-29 08:10:06 -0400 |
commit | c6a2a1770245f654f35f60e1458d4356680f9519 (patch) | |
tree | 0a015269ca839ac2fe91b3d86955997bf7b8686d /kernel | |
parent | 2b022e3d4bf9885f781221c59d86283a2cdfc2ed (diff) |
hrtimer: Add tracepoint for hrtimers
Add tracepoints which cover the life cycle of a hrtimer. The
tracepoints are integrated with the already existing debug_object
debug points as far as possible.
[ tglx: Fixed comments, made output conistent, easier to read and
parse. Fixed output for 32bit archs which do not use the
scalar representation of ktime_t. Hand current time to
trace_hrtimer_expiry_entry instead of calling get_time()
inside of the trace assignment. ]
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Anton Blanchard <anton@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Zhaolei <zhaolei@cn.fujitsu.com>
LKML-Reference: <4A7F8B2B.5020908@cn.fujitsu.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e2f91ecc01a8..b44d1b07377b 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -48,6 +48,8 @@ | |||
48 | 48 | ||
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
50 | 50 | ||
51 | #include <trace/events/timer.h> | ||
52 | |||
51 | /* | 53 | /* |
52 | * The timer bases: | 54 | * The timer bases: |
53 | * | 55 | * |
@@ -441,6 +443,26 @@ static inline void debug_hrtimer_activate(struct hrtimer *timer) { } | |||
441 | static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { } | 443 | static inline void debug_hrtimer_deactivate(struct hrtimer *timer) { } |
442 | #endif | 444 | #endif |
443 | 445 | ||
446 | static inline void | ||
447 | debug_init(struct hrtimer *timer, clockid_t clockid, | ||
448 | enum hrtimer_mode mode) | ||
449 | { | ||
450 | debug_hrtimer_init(timer); | ||
451 | trace_hrtimer_init(timer, clockid, mode); | ||
452 | } | ||
453 | |||
454 | static inline void debug_activate(struct hrtimer *timer) | ||
455 | { | ||
456 | debug_hrtimer_activate(timer); | ||
457 | trace_hrtimer_start(timer); | ||
458 | } | ||
459 | |||
460 | static inline void debug_deactivate(struct hrtimer *timer) | ||
461 | { | ||
462 | debug_hrtimer_deactivate(timer); | ||
463 | trace_hrtimer_cancel(timer); | ||
464 | } | ||
465 | |||
444 | /* High resolution timer related functions */ | 466 | /* High resolution timer related functions */ |
445 | #ifdef CONFIG_HIGH_RES_TIMERS | 467 | #ifdef CONFIG_HIGH_RES_TIMERS |
446 | 468 | ||
@@ -797,7 +819,7 @@ static int enqueue_hrtimer(struct hrtimer *timer, | |||
797 | struct hrtimer *entry; | 819 | struct hrtimer *entry; |
798 | int leftmost = 1; | 820 | int leftmost = 1; |
799 | 821 | ||
800 | debug_hrtimer_activate(timer); | 822 | debug_activate(timer); |
801 | 823 | ||
802 | /* | 824 | /* |
803 | * Find the right place in the rbtree: | 825 | * Find the right place in the rbtree: |
@@ -883,7 +905,7 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base) | |||
883 | * reprogramming happens in the interrupt handler. This is a | 905 | * reprogramming happens in the interrupt handler. This is a |
884 | * rare case and less expensive than a smp call. | 906 | * rare case and less expensive than a smp call. |
885 | */ | 907 | */ |
886 | debug_hrtimer_deactivate(timer); | 908 | debug_deactivate(timer); |
887 | timer_stats_hrtimer_clear_start_info(timer); | 909 | timer_stats_hrtimer_clear_start_info(timer); |
888 | reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases); | 910 | reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases); |
889 | __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, | 911 | __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, |
@@ -1116,7 +1138,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | |||
1116 | void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, | 1138 | void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, |
1117 | enum hrtimer_mode mode) | 1139 | enum hrtimer_mode mode) |
1118 | { | 1140 | { |
1119 | debug_hrtimer_init(timer); | 1141 | debug_init(timer, clock_id, mode); |
1120 | __hrtimer_init(timer, clock_id, mode); | 1142 | __hrtimer_init(timer, clock_id, mode); |
1121 | } | 1143 | } |
1122 | EXPORT_SYMBOL_GPL(hrtimer_init); | 1144 | EXPORT_SYMBOL_GPL(hrtimer_init); |
@@ -1140,7 +1162,7 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) | |||
1140 | } | 1162 | } |
1141 | EXPORT_SYMBOL_GPL(hrtimer_get_res); | 1163 | EXPORT_SYMBOL_GPL(hrtimer_get_res); |
1142 | 1164 | ||
1143 | static void __run_hrtimer(struct hrtimer *timer) | 1165 | static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) |
1144 | { | 1166 | { |
1145 | struct hrtimer_clock_base *base = timer->base; | 1167 | struct hrtimer_clock_base *base = timer->base; |
1146 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; | 1168 | struct hrtimer_cpu_base *cpu_base = base->cpu_base; |
@@ -1149,7 +1171,7 @@ static void __run_hrtimer(struct hrtimer *timer) | |||
1149 | 1171 | ||
1150 | WARN_ON(!irqs_disabled()); | 1172 | WARN_ON(!irqs_disabled()); |
1151 | 1173 | ||
1152 | debug_hrtimer_deactivate(timer); | 1174 | debug_deactivate(timer); |
1153 | __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0); | 1175 | __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0); |
1154 | timer_stats_account_hrtimer(timer); | 1176 | timer_stats_account_hrtimer(timer); |
1155 | fn = timer->function; | 1177 | fn = timer->function; |
@@ -1160,7 +1182,9 @@ static void __run_hrtimer(struct hrtimer *timer) | |||
1160 | * the timer base. | 1182 | * the timer base. |
1161 | */ | 1183 | */ |
1162 | spin_unlock(&cpu_base->lock); | 1184 | spin_unlock(&cpu_base->lock); |
1185 | trace_hrtimer_expire_entry(timer, now); | ||
1163 | restart = fn(timer); | 1186 | restart = fn(timer); |
1187 | trace_hrtimer_expire_exit(timer); | ||
1164 | spin_lock(&cpu_base->lock); | 1188 | spin_lock(&cpu_base->lock); |
1165 | 1189 | ||
1166 | /* | 1190 | /* |
@@ -1271,7 +1295,7 @@ void hrtimer_interrupt(struct clock_event_device *dev) | |||
1271 | break; | 1295 | break; |
1272 | } | 1296 | } |
1273 | 1297 | ||
1274 | __run_hrtimer(timer); | 1298 | __run_hrtimer(timer, &basenow); |
1275 | } | 1299 | } |
1276 | base++; | 1300 | base++; |
1277 | } | 1301 | } |
@@ -1393,7 +1417,7 @@ void hrtimer_run_queues(void) | |||
1393 | hrtimer_get_expires_tv64(timer)) | 1417 | hrtimer_get_expires_tv64(timer)) |
1394 | break; | 1418 | break; |
1395 | 1419 | ||
1396 | __run_hrtimer(timer); | 1420 | __run_hrtimer(timer, &base->softirq_time); |
1397 | } | 1421 | } |
1398 | spin_unlock(&cpu_base->lock); | 1422 | spin_unlock(&cpu_base->lock); |
1399 | } | 1423 | } |
@@ -1569,7 +1593,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, | |||
1569 | while ((node = rb_first(&old_base->active))) { | 1593 | while ((node = rb_first(&old_base->active))) { |
1570 | timer = rb_entry(node, struct hrtimer, node); | 1594 | timer = rb_entry(node, struct hrtimer, node); |
1571 | BUG_ON(hrtimer_callback_running(timer)); | 1595 | BUG_ON(hrtimer_callback_running(timer)); |
1572 | debug_hrtimer_deactivate(timer); | 1596 | debug_deactivate(timer); |
1573 | 1597 | ||
1574 | /* | 1598 | /* |
1575 | * Mark it as STATE_MIGRATE not INACTIVE otherwise the | 1599 | * Mark it as STATE_MIGRATE not INACTIVE otherwise the |