aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2007-02-16 04:28:13 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:59 -0500
commit82f67cd9fca8c8762c15ba7ed0d5747588c1e221 (patch)
tree1ff7e5cc496580b85bb42fb1d7b19dcbef7b7776 /include/linux
parent8bfd9a7a229b5f3d3eda5d7d45c2eebec5b4ba16 (diff)
[PATCH] Add debugging feature /proc/timer_stat
Add /proc/timer_stats support: debugging feature to profile timer expiration. Both the starting site, process/PID and the expiration function is captured. This allows the quick identification of timer event sources in a system. Sample output: # echo 1 > /proc/timer_stats # cat /proc/timer_stats Timer Stats Version: v0.1 Sample period: 4.010 s 24, 0 swapper hrtimer_stop_sched_tick (hrtimer_sched_tick) 11, 0 swapper sk_reset_timer (tcp_delack_timer) 6, 0 swapper hrtimer_stop_sched_tick (hrtimer_sched_tick) 2, 1 swapper queue_delayed_work_on (delayed_work_timer_fn) 17, 0 swapper hrtimer_restart_sched_tick (hrtimer_sched_tick) 2, 1 swapper queue_delayed_work_on (delayed_work_timer_fn) 4, 2050 pcscd do_nanosleep (hrtimer_wakeup) 5, 4179 sshd sk_reset_timer (tcp_write_timer) 4, 2248 yum-updatesd schedule_timeout (process_timeout) 18, 0 swapper hrtimer_restart_sched_tick (hrtimer_sched_tick) 3, 0 swapper sk_reset_timer (tcp_delack_timer) 1, 1 swapper neigh_table_init_no_netlink (neigh_periodic_timer) 2, 1 swapper e1000_up (e1000_watchdog) 1, 1 init schedule_timeout (process_timeout) 100 total events, 25.24 events/sec [ cleanups and hrtimers support from Thomas Gleixner <tglx@linutronix.de> ] [bunk@stusta.de: nr_entries can become static] Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/hrtimer.h45
-rw-r--r--include/linux/timer.h54
2 files changed, 99 insertions, 0 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 4ecd991431b4..93b8757c1ea2 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -119,6 +119,11 @@ struct hrtimer {
119 enum hrtimer_cb_mode cb_mode; 119 enum hrtimer_cb_mode cb_mode;
120 struct list_head cb_entry; 120 struct list_head cb_entry;
121#endif 121#endif
122#ifdef CONFIG_TIMER_STATS
123 void *start_site;
124 char start_comm[16];
125 int start_pid;
126#endif
122}; 127};
123 128
124/** 129/**
@@ -311,4 +316,44 @@ extern unsigned long ktime_divns(const ktime_t kt, s64 div);
311# define ktime_divns(kt, div) (unsigned long)((kt).tv64 / (div)) 316# define ktime_divns(kt, div) (unsigned long)((kt).tv64 / (div))
312#endif 317#endif
313 318
319/*
320 * Timer-statistics info:
321 */
322#ifdef CONFIG_TIMER_STATS
323
324extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
325 void *timerf, char * comm);
326
327static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
328{
329 timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
330 timer->function, timer->start_comm);
331}
332
333extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer,
334 void *addr);
335
336static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
337{
338 __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0));
339}
340
341static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
342{
343 timer->start_site = NULL;
344}
345#else
346static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
347{
348}
349
350static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
351{
352}
353
354static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
355{
356}
357#endif
358
314#endif 359#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 44d41e9d7818..719113b652dd 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -2,6 +2,7 @@
2#define _LINUX_TIMER_H 2#define _LINUX_TIMER_H
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/ktime.h>
5#include <linux/spinlock.h> 6#include <linux/spinlock.h>
6#include <linux/stddef.h> 7#include <linux/stddef.h>
7 8
@@ -15,6 +16,11 @@ struct timer_list {
15 unsigned long data; 16 unsigned long data;
16 17
17 struct tvec_t_base_s *base; 18 struct tvec_t_base_s *base;
19#ifdef CONFIG_TIMER_STATS
20 void *start_site;
21 char start_comm[16];
22 int start_pid;
23#endif
18}; 24};
19 25
20extern struct tvec_t_base_s boot_tvec_bases; 26extern struct tvec_t_base_s boot_tvec_bases;
@@ -73,6 +79,54 @@ extern unsigned long next_timer_interrupt(void);
73 */ 79 */
74extern unsigned long get_next_timer_interrupt(unsigned long now); 80extern unsigned long get_next_timer_interrupt(unsigned long now);
75 81
82/*
83 * Timer-statistics info:
84 */
85#ifdef CONFIG_TIMER_STATS
86
87extern void init_timer_stats(void);
88
89extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
90 void *timerf, char * comm);
91
92static inline void timer_stats_account_timer(struct timer_list *timer)
93{
94 timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
95 timer->function, timer->start_comm);
96}
97
98extern void __timer_stats_timer_set_start_info(struct timer_list *timer,
99 void *addr);
100
101static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
102{
103 __timer_stats_timer_set_start_info(timer, __builtin_return_address(0));
104}
105
106static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
107{
108 timer->start_site = NULL;
109}
110#else
111static inline void init_timer_stats(void)
112{
113}
114
115static inline void timer_stats_account_timer(struct timer_list *timer)
116{
117}
118
119static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
120{
121}
122
123static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
124{
125}
126#endif
127
128extern void delayed_work_timer_fn(unsigned long __data);
129
76/** 130/**
77 * add_timer - start a timer 131 * add_timer - start a timer
78 * @timer: the timer to be added 132 * @timer: the timer to be added