diff options
| author | Venki Pallipadi <venkatesh.pallipadi@intel.com> | 2007-07-16 02:40:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:45 -0400 |
| commit | c5c061b8f9726bc2c25e19dec227933a13d1e6b7 (patch) | |
| tree | e99f68f70df1a01dd383007895befd114a1da8c4 /kernel | |
| parent | e0807061908a7a9441d0f745deb444f7216904cb (diff) | |
Add a flag to indicate deferrable timers in /proc/timer_stats
Add a flag in /proc/timer_stats to indicate deferrable timers. This will
let developers/users to differentiate between types of tiemrs in
/proc/timer_stats.
Deferrable timer and normal timer will appear in /proc/timer_stats as below.
10D, 1 swapper queue_delayed_work_on (delayed_work_timer_fn)
10, 1 swapper queue_delayed_work_on (delayed_work_timer_fn)
Also version of timer_stats changes from v0.1 to v0.2
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: john stultz <johnstul@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/time/timer_stats.c | 14 | ||||
| -rw-r--r-- | kernel/timer.c | 14 |
2 files changed, 25 insertions, 3 deletions
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c index 321693724ad7..9b8a826236dd 100644 --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c | |||
| @@ -68,6 +68,7 @@ struct entry { | |||
| 68 | * Number of timeout events: | 68 | * Number of timeout events: |
| 69 | */ | 69 | */ |
| 70 | unsigned long count; | 70 | unsigned long count; |
| 71 | unsigned int timer_flag; | ||
| 71 | 72 | ||
| 72 | /* | 73 | /* |
| 73 | * We save the command-line string to preserve | 74 | * We save the command-line string to preserve |
| @@ -231,7 +232,8 @@ static struct entry *tstat_lookup(struct entry *entry, char *comm) | |||
| 231 | * incremented. Otherwise the timer is registered in a free slot. | 232 | * incremented. Otherwise the timer is registered in a free slot. |
| 232 | */ | 233 | */ |
| 233 | void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | 234 | void timer_stats_update_stats(void *timer, pid_t pid, void *startf, |
| 234 | void *timerf, char * comm) | 235 | void *timerf, char *comm, |
| 236 | unsigned int timer_flag) | ||
| 235 | { | 237 | { |
| 236 | /* | 238 | /* |
| 237 | * It doesnt matter which lock we take: | 239 | * It doesnt matter which lock we take: |
| @@ -249,6 +251,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
| 249 | input.start_func = startf; | 251 | input.start_func = startf; |
| 250 | input.expire_func = timerf; | 252 | input.expire_func = timerf; |
| 251 | input.pid = pid; | 253 | input.pid = pid; |
| 254 | input.timer_flag = timer_flag; | ||
| 252 | 255 | ||
| 253 | spin_lock_irqsave(lock, flags); | 256 | spin_lock_irqsave(lock, flags); |
| 254 | if (!active) | 257 | if (!active) |
| @@ -295,7 +298,7 @@ static int tstats_show(struct seq_file *m, void *v) | |||
| 295 | period = ktime_to_timespec(time); | 298 | period = ktime_to_timespec(time); |
| 296 | ms = period.tv_nsec / 1000000; | 299 | ms = period.tv_nsec / 1000000; |
| 297 | 300 | ||
| 298 | seq_puts(m, "Timer Stats Version: v0.1\n"); | 301 | seq_puts(m, "Timer Stats Version: v0.2\n"); |
| 299 | seq_printf(m, "Sample period: %ld.%03ld s\n", period.tv_sec, ms); | 302 | seq_printf(m, "Sample period: %ld.%03ld s\n", period.tv_sec, ms); |
| 300 | if (atomic_read(&overflow_count)) | 303 | if (atomic_read(&overflow_count)) |
| 301 | seq_printf(m, "Overflow: %d entries\n", | 304 | seq_printf(m, "Overflow: %d entries\n", |
| @@ -303,8 +306,13 @@ static int tstats_show(struct seq_file *m, void *v) | |||
| 303 | 306 | ||
| 304 | for (i = 0; i < nr_entries; i++) { | 307 | for (i = 0; i < nr_entries; i++) { |
| 305 | entry = entries + i; | 308 | entry = entries + i; |
| 306 | seq_printf(m, "%4lu, %5d %-16s ", | 309 | if (entry->timer_flag & TIMER_STATS_FLAG_DEFERRABLE) { |
| 310 | seq_printf(m, "%4luD, %5d %-16s ", | ||
| 307 | entry->count, entry->pid, entry->comm); | 311 | entry->count, entry->pid, entry->comm); |
| 312 | } else { | ||
| 313 | seq_printf(m, " %4lu, %5d %-16s ", | ||
| 314 | entry->count, entry->pid, entry->comm); | ||
| 315 | } | ||
| 308 | 316 | ||
| 309 | print_name_offset(m, (unsigned long)entry->start_func); | 317 | print_name_offset(m, (unsigned long)entry->start_func); |
| 310 | seq_puts(m, " ("); | 318 | seq_puts(m, " ("); |
diff --git a/kernel/timer.c b/kernel/timer.c index 1ab3106a2b5d..1258371e0d2b 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -305,6 +305,20 @@ void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr) | |||
| 305 | memcpy(timer->start_comm, current->comm, TASK_COMM_LEN); | 305 | memcpy(timer->start_comm, current->comm, TASK_COMM_LEN); |
| 306 | timer->start_pid = current->pid; | 306 | timer->start_pid = current->pid; |
| 307 | } | 307 | } |
| 308 | |||
| 309 | static void timer_stats_account_timer(struct timer_list *timer) | ||
| 310 | { | ||
| 311 | unsigned int flag = 0; | ||
| 312 | |||
| 313 | if (unlikely(tbase_get_deferrable(timer->base))) | ||
| 314 | flag |= TIMER_STATS_FLAG_DEFERRABLE; | ||
| 315 | |||
| 316 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, | ||
| 317 | timer->function, timer->start_comm, flag); | ||
| 318 | } | ||
| 319 | |||
| 320 | #else | ||
| 321 | static void timer_stats_account_timer(struct timer_list *timer) {} | ||
| 308 | #endif | 322 | #endif |
| 309 | 323 | ||
| 310 | /** | 324 | /** |
