@@ -237,29 +237,64 @@ struct lock_key {
237237 * e.g. nr_acquired -> acquired, wait_time_total -> wait_total
238238 */
239239 const char * name ;
240+ /* header: the string printed on the header line */
241+ const char * header ;
242+ /* len: the printing width of the field */
243+ int len ;
244+ /* key: a pointer to function to compare two lock stats for sorting */
240245 int (* key )(struct lock_stat * , struct lock_stat * );
246+ /* print: a pointer to function to print a given lock stats */
247+ void (* print )(struct lock_key * , struct lock_stat * );
248+ /* list: list entry to link this */
249+ struct list_head list ;
241250};
242251
252+ #define PRINT_KEY (member ) \
253+ static void lock_stat_key_print_ ## member(struct lock_key *key, \
254+ struct lock_stat *ls) \
255+ { \
256+ pr_info("%*llu", key->len, (unsigned long long)ls->member); \
257+ }
258+
259+ PRINT_KEY (nr_acquired )
260+ PRINT_KEY (nr_contended )
261+ PRINT_KEY (avg_wait_time )
262+ PRINT_KEY (wait_time_total )
263+ PRINT_KEY (wait_time_max )
264+
265+ static void lock_stat_key_print_wait_time_min (struct lock_key * key ,
266+ struct lock_stat * ls )
267+ {
268+ u64 wait_time = ls -> wait_time_min ;
269+
270+ if (wait_time == ULLONG_MAX )
271+ wait_time = 0 ;
272+
273+ pr_info ("%*" PRIu64 , key -> len , wait_time );
274+ }
275+
276+
243277static const char * sort_key = "acquired" ;
244278
245279static int (* compare )(struct lock_stat * , struct lock_stat * );
246280
247281static struct rb_root sorted ; /* place to store intermediate data */
248282static struct rb_root result ; /* place to store sorted data */
249283
250- #define DEF_KEY_LOCK (name , fn_suffix ) \
251- { #name, lock_stat_key_ ## fn_suffix }
284+ static LIST_HEAD (lock_keys );
285+
286+ #define DEF_KEY_LOCK (name , header , fn_suffix , len ) \
287+ { #name, header, len, lock_stat_key_ ## fn_suffix, lock_stat_key_print_ ## fn_suffix, {} }
252288struct lock_key keys [] = {
253- DEF_KEY_LOCK (acquired , nr_acquired ),
254- DEF_KEY_LOCK (contended , nr_contended ),
255- DEF_KEY_LOCK (avg_wait , avg_wait_time ),
256- DEF_KEY_LOCK (wait_total , wait_time_total ),
257- DEF_KEY_LOCK (wait_min , wait_time_min ),
258- DEF_KEY_LOCK (wait_max , wait_time_max ),
289+ DEF_KEY_LOCK (acquired , "acquired" , nr_acquired , 10 ),
290+ DEF_KEY_LOCK (contended , "contended" , nr_contended , 10 ),
291+ DEF_KEY_LOCK (avg_wait , "avg wait (ns)" , avg_wait_time , 15 ),
292+ DEF_KEY_LOCK (wait_total , "total wait (ns)" , wait_time_total , 15 ),
293+ DEF_KEY_LOCK (wait_max , "max wait (ns)" , wait_time_max , 15 ),
294+ DEF_KEY_LOCK (wait_min , "min wait (ns)" , wait_time_min , 15 ),
259295
260296 /* extra comparisons much complicated should be here */
261-
262- { NULL , NULL }
297+ { }
263298};
264299
265300static int select_key (void )
@@ -278,6 +313,16 @@ static int select_key(void)
278313 return -1 ;
279314}
280315
316+ static int setup_output_field (void )
317+ {
318+ int i ;
319+
320+ for (i = 0 ; keys [i ].name ; i ++ )
321+ list_add_tail (& keys [i ].list , & lock_keys );
322+
323+ return 0 ;
324+ }
325+
281326static void combine_lock_stats (struct lock_stat * st )
282327{
283328 struct rb_node * * rb = & sorted .rb_node ;
@@ -753,18 +798,13 @@ static void print_bad_events(int bad, int total)
753798static void print_result (void )
754799{
755800 struct lock_stat * st ;
801+ struct lock_key * key ;
756802 char cut_name [20 ];
757803 int bad , total ;
758804
759805 pr_info ("%20s " , "Name" );
760- pr_info ("%10s " , "acquired" );
761- pr_info ("%10s " , "contended" );
762-
763- pr_info ("%15s " , "avg wait (ns)" );
764- pr_info ("%15s " , "total wait (ns)" );
765- pr_info ("%15s " , "max wait (ns)" );
766- pr_info ("%15s " , "min wait (ns)" );
767-
806+ list_for_each_entry (key , & lock_keys , list )
807+ pr_info ("%*s " , key -> len , key -> header );
768808 pr_info ("\n\n" );
769809
770810 bad = total = 0 ;
@@ -789,14 +829,10 @@ static void print_result(void)
789829 pr_info ("%20s " , cut_name );
790830 }
791831
792- pr_info ("%10u " , st -> nr_acquired );
793- pr_info ("%10u " , st -> nr_contended );
794-
795- pr_info ("%15" PRIu64 " " , st -> avg_wait_time );
796- pr_info ("%15" PRIu64 " " , st -> wait_time_total );
797- pr_info ("%15" PRIu64 " " , st -> wait_time_max );
798- pr_info ("%15" PRIu64 " " , st -> wait_time_min == ULLONG_MAX ?
799- 0 : st -> wait_time_min );
832+ list_for_each_entry (key , & lock_keys , list ) {
833+ key -> print (key , st );
834+ pr_info (" " );
835+ }
800836 pr_info ("\n" );
801837 }
802838
@@ -966,6 +1002,9 @@ static int __cmd_report(bool display_info)
9661002 goto out_delete ;
9671003 }
9681004
1005+ if (setup_output_field ())
1006+ goto out_delete ;
1007+
9691008 if (select_key ())
9701009 goto out_delete ;
9711010
0 commit comments