Add a flag to indicate deferrable timers in /proc/timer_stats
PATCH 1/1 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 <[email protected]>
include/linux/hrtimer.h +3 -2
@@ -329,12 +329,13 @@#ifdef CONFIG_TIMER_STATS extern void timer_stats_update_stats (void *timer,pid_t pid,void *startf, -void *timerf,char * comm); +void *timerf,char * comm, +unsigned int timer_flag);static inline void timer_stats_account_hrtimer (struct hrtimer *timer) {timer_stats_update_stats (timer, timer->start_pid, timer->start_site, - timer->function, timer->start_comm); + timer->function, timer->start_comm,0 ); } extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer,
kernel/timer.c +14 -0
@@ -305,6 +305,20 @@memcpy (timer->start_comm, current->comm,TASK_COMM_LEN ); timer->start_pid = current->pid; } + +static void timer_stats_account_timer (struct timer_list *timer) +{ +unsigned int flag =0 ; + +if (unlikely (tbase_get_deferrable (timer->base))) + flag |=TIMER_STATS_FLAG_DEFERRABLE ; + +timer_stats_update_stats (timer, timer->start_pid, timer->start_site, + timer->function, timer->start_comm, flag); +} + +#else +static void timer_stats_account_timer (struct timer_list *timer) {}#endif /**
kernel/time/timer_stats.c +11 -3
@@ -68,6 +68,7 @@* Number of timeout events: */ unsigned long count; +unsigned int timer_flag;/* * We save the command-line string to preserve
@@ -227,7 +228,8 @@* incremented. Otherwise the timer is registered in a free slot. */ void timer_stats_update_stats (void *timer,pid_t pid,void *startf, -void *timerf,char * comm) +void *timerf,char * comm, +unsigned int timer_flag) {/* * It doesnt matter which lock we take:
@@ -240,6 +242,7 @@ input.start_func = startf; input.expire_func = timerf; input.pid = pid; + input.timer_flag = timer_flag;spin_lock_irqsave (lock, flags);if (!active)
@@ -286,7 +289,7 @@ period =ktime_to_timespec (time); ms = period.tv_nsec /1000000 ; -seq_puts (m,"Timer Stats Version: v0.1\n" ); +seq_puts (m,"Timer Stats Version: v0.2\n" );seq_printf (m,"Sample period: %ld.%03ld s\n" , period.tv_sec, ms);if (atomic_read (&overflow_count)) seq_printf(m, "Overflow: %d entries\n",
@@ -294,8 +297,13 @@for (i =0 ; i < nr_entries; i++) { entry = entries + i; -seq_printf (m,"%4lu, %5d %-16s " , +if (entry->timer_flag &TIMER_STATS_FLAG_DEFERRABLE ) { +seq_printf (m,"%4luD, %5d %-16s " , entry->count, entry->pid, entry->comm); + }else { +seq_printf (m," %4lu, %5d %-16s " , + entry->count, entry->pid, entry->comm); + }print_name_offset (m, (unsigned long )entry->start_func);seq_puts (m," (" );
include/linux/timer.h +4 -11
@@ -85,16 +85,13 @@*/ #ifdef CONFIG_TIMER_STATS +#define TIMER_STATS_FLAG_DEFERRABLE 0x1 +extern void init_timer_stats (void );extern void timer_stats_update_stats (void *timer,pid_t pid,void *startf, -void *timerf,char * comm); - -static inline void timer_stats_account_timer (struct timer_list *timer) -{ -timer_stats_update_stats (timer, timer->start_pid, timer->start_site, - timer->function, timer->start_comm); -} +void *timerf,char * comm, +unsigned int timer_flag);extern void __timer_stats_timer_set_start_info (struct timer_list *timer,void *addr);
@@ -113,10 +110,6 @@ { } -static inline void timer_stats_account_timer (struct timer_list *timer) -{ -} -static inline void timer_stats_timer_set_start_info (struct timer_list *timer) { }
Documentation/hrtimer/timer_stats.txt +4 -0
@@ -66,3 +66,7 @@ Thomas, Ingo +Added flag to indicate 'deferrable timer' in /proc/timer_stats. A deferrable +timer will appear as follows + 10D, 1 swapper queue_delayed_work_on (delayed_work_timer_fn) +