@@ -507,6 +507,7 @@ enum hist_field_flags {
507
507
HIST_FIELD_FL_BUCKET = 1 << 17 ,
508
508
HIST_FIELD_FL_CONST = 1 << 18 ,
509
509
HIST_FIELD_FL_PERCENT = 1 << 19 ,
510
+ HIST_FIELD_FL_GRAPH = 1 << 20 ,
510
511
};
511
512
512
513
struct var_defs {
@@ -1710,6 +1711,8 @@ static const char *get_hist_field_flags(struct hist_field *hist_field)
1710
1711
flags_str = "usecs" ;
1711
1712
else if (hist_field -> flags & HIST_FIELD_FL_PERCENT )
1712
1713
flags_str = "percent" ;
1714
+ else if (hist_field -> flags & HIST_FIELD_FL_GRAPH )
1715
+ flags_str = "graph" ;
1713
1716
1714
1717
return flags_str ;
1715
1718
}
@@ -2322,6 +2325,10 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
2322
2325
if (* flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY ))
2323
2326
goto error ;
2324
2327
* flags |= HIST_FIELD_FL_PERCENT ;
2328
+ } else if (strncmp (modifier , "graph" , 5 ) == 0 ) {
2329
+ if (* flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY ))
2330
+ goto error ;
2331
+ * flags |= HIST_FIELD_FL_GRAPH ;
2325
2332
} else {
2326
2333
error :
2327
2334
hist_err (tr , HIST_ERR_BAD_FIELD_MODIFIER , errpos (modifier ));
@@ -5316,20 +5323,52 @@ static inline unsigned int __get_percentage(u64 val, u64 total)
5316
5323
return val ? UINT_MAX : 0 ;
5317
5324
}
5318
5325
5326
+ #define BAR_CHAR '#'
5327
+
5328
+ static inline const char * __fill_bar_str (char * buf , int size , u64 val , u64 max )
5329
+ {
5330
+ unsigned int len = __get_percentage (val , max );
5331
+ int i ;
5332
+
5333
+ if (len == UINT_MAX ) {
5334
+ snprintf (buf , size , "[ERROR]" );
5335
+ return buf ;
5336
+ }
5337
+
5338
+ len = len * size / 10000 ;
5339
+ for (i = 0 ; i < len && i < size ; i ++ )
5340
+ buf [i ] = BAR_CHAR ;
5341
+ while (i < size )
5342
+ buf [i ++ ] = ' ' ;
5343
+ buf [size ] = '\0' ;
5344
+
5345
+ return buf ;
5346
+ }
5347
+
5348
+ struct hist_val_stat {
5349
+ u64 max ;
5350
+ u64 total ;
5351
+ };
5352
+
5319
5353
static void hist_trigger_print_val (struct seq_file * m , unsigned int idx ,
5320
5354
const char * field_name , unsigned long flags ,
5321
- u64 * totals , struct tracing_map_elt * elt )
5355
+ struct hist_val_stat * stats ,
5356
+ struct tracing_map_elt * elt )
5322
5357
{
5323
5358
u64 val = tracing_map_read_sum (elt , idx );
5324
5359
unsigned int pc ;
5360
+ char bar [21 ];
5325
5361
5326
5362
if (flags & HIST_FIELD_FL_PERCENT ) {
5327
- pc = __get_percentage (val , totals [idx ]);
5363
+ pc = __get_percentage (val , stats [idx ]. total );
5328
5364
if (pc == UINT_MAX )
5329
5365
seq_printf (m , " %s (%%):[ERROR]" , field_name );
5330
5366
else
5331
5367
seq_printf (m , " %s (%%): %3u.%02u" , field_name ,
5332
5368
pc / 100 , pc % 100 );
5369
+ } else if (flags & HIST_FIELD_FL_GRAPH ) {
5370
+ seq_printf (m , " %s: %20s" , field_name ,
5371
+ __fill_bar_str (bar , 20 , val , stats [idx ].max ));
5333
5372
} else if (flags & HIST_FIELD_FL_HEX ) {
5334
5373
seq_printf (m , " %s: %10llx" , field_name , val );
5335
5374
} else {
@@ -5339,7 +5378,7 @@ static void hist_trigger_print_val(struct seq_file *m, unsigned int idx,
5339
5378
5340
5379
static void hist_trigger_entry_print (struct seq_file * m ,
5341
5380
struct hist_trigger_data * hist_data ,
5342
- u64 * totals ,
5381
+ struct hist_val_stat * stats ,
5343
5382
void * key ,
5344
5383
struct tracing_map_elt * elt )
5345
5384
{
@@ -5350,7 +5389,7 @@ static void hist_trigger_entry_print(struct seq_file *m,
5350
5389
hist_trigger_print_key (m , hist_data , key , elt );
5351
5390
5352
5391
/* At first, show the raw hitcount always */
5353
- hist_trigger_print_val (m , i , "hitcount" , 0 , totals , elt );
5392
+ hist_trigger_print_val (m , i , "hitcount" , 0 , stats , elt );
5354
5393
5355
5394
for (i = 1 ; i < hist_data -> n_vals ; i ++ ) {
5356
5395
field_name = hist_field_name (hist_data -> fields [i ], 0 );
@@ -5360,7 +5399,7 @@ static void hist_trigger_entry_print(struct seq_file *m,
5360
5399
continue ;
5361
5400
5362
5401
seq_puts (m , " " );
5363
- hist_trigger_print_val (m , i , field_name , flags , totals , elt );
5402
+ hist_trigger_print_val (m , i , field_name , flags , stats , elt );
5364
5403
}
5365
5404
5366
5405
print_actions (m , hist_data , elt );
@@ -5374,36 +5413,42 @@ static int print_entries(struct seq_file *m,
5374
5413
struct tracing_map_sort_entry * * sort_entries = NULL ;
5375
5414
struct tracing_map * map = hist_data -> map ;
5376
5415
int i , j , n_entries ;
5377
- u64 * totals = NULL ;
5416
+ struct hist_val_stat * stats = NULL ;
5417
+ u64 val ;
5378
5418
5379
5419
n_entries = tracing_map_sort_entries (map , hist_data -> sort_keys ,
5380
5420
hist_data -> n_sort_keys ,
5381
5421
& sort_entries );
5382
5422
if (n_entries < 0 )
5383
5423
return n_entries ;
5384
5424
5425
+ /* Calculate the max and the total for each field if needed. */
5385
5426
for (j = 0 ; j < hist_data -> n_vals ; j ++ ) {
5386
- if (!(hist_data -> fields [j ]-> flags & HIST_FIELD_FL_PERCENT ))
5427
+ if (!(hist_data -> fields [j ]-> flags &
5428
+ (HIST_FIELD_FL_PERCENT | HIST_FIELD_FL_GRAPH )))
5387
5429
continue ;
5388
- if (!totals ) {
5389
- totals = kcalloc (hist_data -> n_vals , sizeof (u64 ),
5390
- GFP_KERNEL );
5391
- if (!totals ) {
5430
+ if (!stats ) {
5431
+ stats = kcalloc (hist_data -> n_vals , sizeof (* stats ),
5432
+ GFP_KERNEL );
5433
+ if (!stats ) {
5392
5434
n_entries = - ENOMEM ;
5393
5435
goto out ;
5394
5436
}
5395
5437
}
5396
- for (i = 0 ; i < n_entries ; i ++ )
5397
- totals [j ] += tracing_map_read_sum (
5398
- sort_entries [i ]-> elt , j );
5438
+ for (i = 0 ; i < n_entries ; i ++ ) {
5439
+ val = tracing_map_read_sum (sort_entries [i ]-> elt , j );
5440
+ stats [j ].total += val ;
5441
+ if (stats [j ].max < val )
5442
+ stats [j ].max = val ;
5443
+ }
5399
5444
}
5400
5445
5401
5446
for (i = 0 ; i < n_entries ; i ++ )
5402
- hist_trigger_entry_print (m , hist_data , totals ,
5447
+ hist_trigger_entry_print (m , hist_data , stats ,
5403
5448
sort_entries [i ]-> key ,
5404
5449
sort_entries [i ]-> elt );
5405
5450
5406
- kfree (totals );
5451
+ kfree (stats );
5407
5452
out :
5408
5453
tracing_map_destroy_sort_entries (sort_entries , n_entries );
5409
5454
0 commit comments