@@ -6478,6 +6478,279 @@ const struct file_operations event_hist_fops = {
6478
6478
.release = single_release ,
6479
6479
};
6480
6480
6481
+ #ifdef CONFIG_HIST_TRIGGERS_DEBUG
6482
+ static void hist_field_debug_show_flags (struct seq_file * m ,
6483
+ unsigned long flags )
6484
+ {
6485
+ seq_puts (m , " flags:\n" );
6486
+
6487
+ if (flags & HIST_FIELD_FL_KEY )
6488
+ seq_puts (m , " HIST_FIELD_FL_KEY\n" );
6489
+ else if (flags & HIST_FIELD_FL_HITCOUNT )
6490
+ seq_puts (m , " VAL: HIST_FIELD_FL_HITCOUNT\n" );
6491
+ else if (flags & HIST_FIELD_FL_VAR )
6492
+ seq_puts (m , " HIST_FIELD_FL_VAR\n" );
6493
+ else if (flags & HIST_FIELD_FL_VAR_REF )
6494
+ seq_puts (m , " HIST_FIELD_FL_VAR_REF\n" );
6495
+ else
6496
+ seq_puts (m , " VAL: normal u64 value\n" );
6497
+
6498
+ if (flags & HIST_FIELD_FL_ALIAS )
6499
+ seq_puts (m , " HIST_FIELD_FL_ALIAS\n" );
6500
+ }
6501
+
6502
+ static int hist_field_debug_show (struct seq_file * m ,
6503
+ struct hist_field * field , unsigned long flags )
6504
+ {
6505
+ if ((field -> flags & flags ) != flags ) {
6506
+ seq_printf (m , "ERROR: bad flags - %lx\n" , flags );
6507
+ return - EINVAL ;
6508
+ }
6509
+
6510
+ hist_field_debug_show_flags (m , field -> flags );
6511
+ if (field -> field )
6512
+ seq_printf (m , " ftrace_event_field name: %s\n" ,
6513
+ field -> field -> name );
6514
+
6515
+ if (field -> flags & HIST_FIELD_FL_VAR ) {
6516
+ seq_printf (m , " var.name: %s\n" , field -> var .name );
6517
+ seq_printf (m , " var.idx (into tracing_map_elt.vars[]): %u\n" ,
6518
+ field -> var .idx );
6519
+ }
6520
+
6521
+ if (field -> flags & HIST_FIELD_FL_ALIAS )
6522
+ seq_printf (m , " var_ref_idx (into hist_data->var_refs[]): %u\n" ,
6523
+ field -> var_ref_idx );
6524
+
6525
+ if (field -> flags & HIST_FIELD_FL_VAR_REF ) {
6526
+ seq_printf (m , " name: %s\n" , field -> name );
6527
+ seq_printf (m , " var.idx (into tracing_map_elt.vars[]): %u\n" ,
6528
+ field -> var .idx );
6529
+ seq_printf (m , " var.hist_data: %p\n" , field -> var .hist_data );
6530
+ seq_printf (m , " var_ref_idx (into hist_data->var_refs[]): %u\n" ,
6531
+ field -> var_ref_idx );
6532
+ if (field -> system )
6533
+ seq_printf (m , " system: %s\n" , field -> system );
6534
+ if (field -> event_name )
6535
+ seq_printf (m , " event_name: %s\n" , field -> event_name );
6536
+ }
6537
+
6538
+ seq_printf (m , " type: %s\n" , field -> type );
6539
+ seq_printf (m , " size: %u\n" , field -> size );
6540
+ seq_printf (m , " is_signed: %u\n" , field -> is_signed );
6541
+
6542
+ return 0 ;
6543
+ }
6544
+
6545
+ static int field_var_debug_show (struct seq_file * m ,
6546
+ struct field_var * field_var , unsigned int i ,
6547
+ bool save_vars )
6548
+ {
6549
+ const char * vars_name = save_vars ? "save_vars" : "field_vars" ;
6550
+ struct hist_field * field ;
6551
+ int ret = 0 ;
6552
+
6553
+ seq_printf (m , "\n hist_data->%s[%d]:\n" , vars_name , i );
6554
+
6555
+ field = field_var -> var ;
6556
+
6557
+ seq_printf (m , "\n %s[%d].var:\n" , vars_name , i );
6558
+
6559
+ hist_field_debug_show_flags (m , field -> flags );
6560
+ seq_printf (m , " var.name: %s\n" , field -> var .name );
6561
+ seq_printf (m , " var.idx (into tracing_map_elt.vars[]): %u\n" ,
6562
+ field -> var .idx );
6563
+
6564
+ field = field_var -> val ;
6565
+
6566
+ seq_printf (m , "\n %s[%d].val:\n" , vars_name , i );
6567
+ if (field -> field )
6568
+ seq_printf (m , " ftrace_event_field name: %s\n" ,
6569
+ field -> field -> name );
6570
+ else {
6571
+ ret = - EINVAL ;
6572
+ goto out ;
6573
+ }
6574
+
6575
+ seq_printf (m , " type: %s\n" , field -> type );
6576
+ seq_printf (m , " size: %u\n" , field -> size );
6577
+ seq_printf (m , " is_signed: %u\n" , field -> is_signed );
6578
+ out :
6579
+ return ret ;
6580
+ }
6581
+
6582
+ static int hist_action_debug_show (struct seq_file * m ,
6583
+ struct action_data * data , int i )
6584
+ {
6585
+ int ret = 0 ;
6586
+
6587
+ if (data -> handler == HANDLER_ONMAX ||
6588
+ data -> handler == HANDLER_ONCHANGE ) {
6589
+ seq_printf (m , "\n hist_data->actions[%d].track_data.var_ref:\n" , i );
6590
+ ret = hist_field_debug_show (m , data -> track_data .var_ref ,
6591
+ HIST_FIELD_FL_VAR_REF );
6592
+ if (ret )
6593
+ goto out ;
6594
+
6595
+ seq_printf (m , "\n hist_data->actions[%d].track_data.track_var:\n" , i );
6596
+ ret = hist_field_debug_show (m , data -> track_data .track_var ,
6597
+ HIST_FIELD_FL_VAR );
6598
+ if (ret )
6599
+ goto out ;
6600
+ }
6601
+
6602
+ if (data -> handler == HANDLER_ONMATCH ) {
6603
+ seq_printf (m , "\n hist_data->actions[%d].match_data.event_system: %s\n" ,
6604
+ i , data -> match_data .event_system );
6605
+ seq_printf (m , " hist_data->actions[%d].match_data.event: %s\n" ,
6606
+ i , data -> match_data .event );
6607
+ }
6608
+ out :
6609
+ return ret ;
6610
+ }
6611
+
6612
+ static int hist_actions_debug_show (struct seq_file * m ,
6613
+ struct hist_trigger_data * hist_data )
6614
+ {
6615
+ int i , ret = 0 ;
6616
+
6617
+ if (hist_data -> n_actions )
6618
+ seq_puts (m , "\n action tracking variables (for onmax()/onchange()/onmatch()):\n" );
6619
+
6620
+ for (i = 0 ; i < hist_data -> n_actions ; i ++ ) {
6621
+ struct action_data * action = hist_data -> actions [i ];
6622
+
6623
+ ret = hist_action_debug_show (m , action , i );
6624
+ if (ret )
6625
+ goto out ;
6626
+ }
6627
+
6628
+ if (hist_data -> n_save_vars )
6629
+ seq_puts (m , "\n save action variables (save() params):\n" );
6630
+
6631
+ for (i = 0 ; i < hist_data -> n_save_vars ; i ++ ) {
6632
+ ret = field_var_debug_show (m , hist_data -> save_vars [i ], i , true);
6633
+ if (ret )
6634
+ goto out ;
6635
+ }
6636
+ out :
6637
+ return ret ;
6638
+ }
6639
+
6640
+ static void hist_trigger_debug_show (struct seq_file * m ,
6641
+ struct event_trigger_data * data , int n )
6642
+ {
6643
+ struct hist_trigger_data * hist_data ;
6644
+ int i , ret ;
6645
+
6646
+ if (n > 0 )
6647
+ seq_puts (m , "\n\n" );
6648
+
6649
+ seq_puts (m , "# event histogram\n#\n# trigger info: " );
6650
+ data -> ops -> print (m , data -> ops , data );
6651
+ seq_puts (m , "#\n\n" );
6652
+
6653
+ hist_data = data -> private_data ;
6654
+
6655
+ seq_printf (m , "hist_data: %p\n\n" , hist_data );
6656
+ seq_printf (m , " n_vals: %u\n" , hist_data -> n_vals );
6657
+ seq_printf (m , " n_keys: %u\n" , hist_data -> n_keys );
6658
+ seq_printf (m , " n_fields: %u\n" , hist_data -> n_fields );
6659
+
6660
+ seq_puts (m , "\n val fields:\n\n" );
6661
+
6662
+ seq_puts (m , " hist_data->fields[0]:\n" );
6663
+ ret = hist_field_debug_show (m , hist_data -> fields [0 ],
6664
+ HIST_FIELD_FL_HITCOUNT );
6665
+ if (ret )
6666
+ return ;
6667
+
6668
+ for (i = 1 ; i < hist_data -> n_vals ; i ++ ) {
6669
+ seq_printf (m , "\n hist_data->fields[%d]:\n" , i );
6670
+ ret = hist_field_debug_show (m , hist_data -> fields [i ], 0 );
6671
+ if (ret )
6672
+ return ;
6673
+ }
6674
+
6675
+ seq_puts (m , "\n key fields:\n" );
6676
+
6677
+ for (i = hist_data -> n_vals ; i < hist_data -> n_fields ; i ++ ) {
6678
+ seq_printf (m , "\n hist_data->fields[%d]:\n" , i );
6679
+ ret = hist_field_debug_show (m , hist_data -> fields [i ],
6680
+ HIST_FIELD_FL_KEY );
6681
+ if (ret )
6682
+ return ;
6683
+ }
6684
+
6685
+ if (hist_data -> n_var_refs )
6686
+ seq_puts (m , "\n variable reference fields:\n" );
6687
+
6688
+ for (i = 0 ; i < hist_data -> n_var_refs ; i ++ ) {
6689
+ seq_printf (m , "\n hist_data->var_refs[%d]:\n" , i );
6690
+ ret = hist_field_debug_show (m , hist_data -> var_refs [i ],
6691
+ HIST_FIELD_FL_VAR_REF );
6692
+ if (ret )
6693
+ return ;
6694
+ }
6695
+
6696
+ if (hist_data -> n_field_vars )
6697
+ seq_puts (m , "\n field variables:\n" );
6698
+
6699
+ for (i = 0 ; i < hist_data -> n_field_vars ; i ++ ) {
6700
+ ret = field_var_debug_show (m , hist_data -> field_vars [i ], i , false);
6701
+ if (ret )
6702
+ return ;
6703
+ }
6704
+
6705
+ ret = hist_actions_debug_show (m , hist_data );
6706
+ if (ret )
6707
+ return ;
6708
+ }
6709
+
6710
+ static int hist_debug_show (struct seq_file * m , void * v )
6711
+ {
6712
+ struct event_trigger_data * data ;
6713
+ struct trace_event_file * event_file ;
6714
+ int n = 0 , ret = 0 ;
6715
+
6716
+ mutex_lock (& event_mutex );
6717
+
6718
+ event_file = event_file_data (m -> private );
6719
+ if (unlikely (!event_file )) {
6720
+ ret = - ENODEV ;
6721
+ goto out_unlock ;
6722
+ }
6723
+
6724
+ list_for_each_entry (data , & event_file -> triggers , list ) {
6725
+ if (data -> cmd_ops -> trigger_type == ETT_EVENT_HIST )
6726
+ hist_trigger_debug_show (m , data , n ++ );
6727
+ }
6728
+
6729
+ out_unlock :
6730
+ mutex_unlock (& event_mutex );
6731
+
6732
+ return ret ;
6733
+ }
6734
+
6735
+ static int event_hist_debug_open (struct inode * inode , struct file * file )
6736
+ {
6737
+ int ret ;
6738
+
6739
+ ret = security_locked_down (LOCKDOWN_TRACEFS );
6740
+ if (ret )
6741
+ return ret ;
6742
+
6743
+ return single_open (file , hist_debug_show , file );
6744
+ }
6745
+
6746
+ const struct file_operations event_hist_debug_fops = {
6747
+ .open = event_hist_debug_open ,
6748
+ .read = seq_read ,
6749
+ .llseek = seq_lseek ,
6750
+ .release = single_release ,
6751
+ };
6752
+ #endif
6753
+
6481
6754
static void hist_field_print (struct seq_file * m , struct hist_field * hist_field )
6482
6755
{
6483
6756
const char * field_name = hist_field_name (hist_field , 0 );
0 commit comments