@@ -237,29 +237,64 @@ struct lock_key {
237
237
* e.g. nr_acquired -> acquired, wait_time_total -> wait_total
238
238
*/
239
239
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 */
240
245
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 ;
241
250
};
242
251
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
+
243
277
static const char * sort_key = "acquired" ;
244
278
245
279
static int (* compare )(struct lock_stat * , struct lock_stat * );
246
280
247
281
static struct rb_root sorted ; /* place to store intermediate data */
248
282
static struct rb_root result ; /* place to store sorted data */
249
283
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, {} }
252
288
struct 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 ),
259
295
260
296
/* extra comparisons much complicated should be here */
261
-
262
- { NULL , NULL }
297
+ { }
263
298
};
264
299
265
300
static int select_key (void )
@@ -278,6 +313,16 @@ static int select_key(void)
278
313
return -1 ;
279
314
}
280
315
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
+
281
326
static void combine_lock_stats (struct lock_stat * st )
282
327
{
283
328
struct rb_node * * rb = & sorted .rb_node ;
@@ -753,18 +798,13 @@ static void print_bad_events(int bad, int total)
753
798
static void print_result (void )
754
799
{
755
800
struct lock_stat * st ;
801
+ struct lock_key * key ;
756
802
char cut_name [20 ];
757
803
int bad , total ;
758
804
759
805
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 );
768
808
pr_info ("\n\n" );
769
809
770
810
bad = total = 0 ;
@@ -789,14 +829,10 @@ static void print_result(void)
789
829
pr_info ("%20s " , cut_name );
790
830
}
791
831
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
+ }
800
836
pr_info ("\n" );
801
837
}
802
838
@@ -966,6 +1002,9 @@ static int __cmd_report(bool display_info)
966
1002
goto out_delete ;
967
1003
}
968
1004
1005
+ if (setup_output_field ())
1006
+ goto out_delete ;
1007
+
969
1008
if (select_key ())
970
1009
goto out_delete ;
971
1010
0 commit comments