@@ -116,6 +116,7 @@ struct hist_field {
116116 struct ftrace_event_field * field ;
117117 unsigned long flags ;
118118 hist_field_fn_t fn ;
119+ unsigned int ref ;
119120 unsigned int size ;
120121 unsigned int offset ;
121122 unsigned int is_signed ;
@@ -1766,11 +1767,13 @@ static struct hist_field *find_var(struct hist_trigger_data *hist_data,
17661767 struct event_trigger_data * test ;
17671768 struct hist_field * hist_field ;
17681769
1770+ lockdep_assert_held (& event_mutex );
1771+
17691772 hist_field = find_var_field (hist_data , var_name );
17701773 if (hist_field )
17711774 return hist_field ;
17721775
1773- list_for_each_entry_rcu (test , & file -> triggers , list ) {
1776+ list_for_each_entry (test , & file -> triggers , list ) {
17741777 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
17751778 test_data = test -> private_data ;
17761779 hist_field = find_var_field (test_data , var_name );
@@ -1820,7 +1823,9 @@ static struct hist_field *find_file_var(struct trace_event_file *file,
18201823 struct event_trigger_data * test ;
18211824 struct hist_field * hist_field ;
18221825
1823- list_for_each_entry_rcu (test , & file -> triggers , list ) {
1826+ lockdep_assert_held (& event_mutex );
1827+
1828+ list_for_each_entry (test , & file -> triggers , list ) {
18241829 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
18251830 test_data = test -> private_data ;
18261831 hist_field = find_var_field (test_data , var_name );
@@ -2423,8 +2428,16 @@ static int contains_operator(char *str)
24232428 return field_op ;
24242429}
24252430
2431+ static void get_hist_field (struct hist_field * hist_field )
2432+ {
2433+ hist_field -> ref ++ ;
2434+ }
2435+
24262436static void __destroy_hist_field (struct hist_field * hist_field )
24272437{
2438+ if (-- hist_field -> ref > 1 )
2439+ return ;
2440+
24282441 kfree (hist_field -> var .name );
24292442 kfree (hist_field -> name );
24302443 kfree (hist_field -> type );
@@ -2466,6 +2479,8 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
24662479 if (!hist_field )
24672480 return NULL ;
24682481
2482+ hist_field -> ref = 1 ;
2483+
24692484 hist_field -> hist_data = hist_data ;
24702485
24712486 if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS )
@@ -2661,6 +2676,17 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
26612676{
26622677 unsigned long flags = HIST_FIELD_FL_VAR_REF ;
26632678 struct hist_field * ref_field ;
2679+ int i ;
2680+
2681+ /* Check if the variable already exists */
2682+ for (i = 0 ; i < hist_data -> n_var_refs ; i ++ ) {
2683+ ref_field = hist_data -> var_refs [i ];
2684+ if (ref_field -> var .idx == var_field -> var .idx &&
2685+ ref_field -> var .hist_data == var_field -> hist_data ) {
2686+ get_hist_field (ref_field );
2687+ return ref_field ;
2688+ }
2689+ }
26642690
26652691 ref_field = create_hist_field (var_field -> hist_data , NULL , flags , NULL );
26662692 if (ref_field ) {
@@ -3115,7 +3141,9 @@ static char *find_trigger_filter(struct hist_trigger_data *hist_data,
31153141{
31163142 struct event_trigger_data * test ;
31173143
3118- list_for_each_entry_rcu (test , & file -> triggers , list ) {
3144+ lockdep_assert_held (& event_mutex );
3145+
3146+ list_for_each_entry (test , & file -> triggers , list ) {
31193147 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
31203148 if (test -> private_data == hist_data )
31213149 return test -> filter_str ;
@@ -3166,9 +3194,11 @@ find_compatible_hist(struct hist_trigger_data *target_hist_data,
31663194 struct event_trigger_data * test ;
31673195 unsigned int n_keys ;
31683196
3197+ lockdep_assert_held (& event_mutex );
3198+
31693199 n_keys = target_hist_data -> n_fields - target_hist_data -> n_vals ;
31703200
3171- list_for_each_entry_rcu (test , & file -> triggers , list ) {
3201+ list_for_each_entry (test , & file -> triggers , list ) {
31723202 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
31733203 hist_data = test -> private_data ;
31743204
@@ -5528,7 +5558,7 @@ static int hist_show(struct seq_file *m, void *v)
55285558 goto out_unlock ;
55295559 }
55305560
5531- list_for_each_entry_rcu (data , & event_file -> triggers , list ) {
5561+ list_for_each_entry (data , & event_file -> triggers , list ) {
55325562 if (data -> cmd_ops -> trigger_type == ETT_EVENT_HIST )
55335563 hist_trigger_show (m , data , n ++ );
55345564 }
@@ -5921,7 +5951,9 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
59215951 if (hist_data -> attrs -> name && !named_data )
59225952 goto new ;
59235953
5924- list_for_each_entry_rcu (test , & file -> triggers , list ) {
5954+ lockdep_assert_held (& event_mutex );
5955+
5956+ list_for_each_entry (test , & file -> triggers , list ) {
59255957 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
59265958 if (!hist_trigger_match (data , test , named_data , false))
59275959 continue ;
@@ -6005,10 +6037,12 @@ static bool have_hist_trigger_match(struct event_trigger_data *data,
60056037 struct event_trigger_data * test , * named_data = NULL ;
60066038 bool match = false;
60076039
6040+ lockdep_assert_held (& event_mutex );
6041+
60086042 if (hist_data -> attrs -> name )
60096043 named_data = find_named_trigger (hist_data -> attrs -> name );
60106044
6011- list_for_each_entry_rcu (test , & file -> triggers , list ) {
6045+ list_for_each_entry (test , & file -> triggers , list ) {
60126046 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
60136047 if (hist_trigger_match (data , test , named_data , false)) {
60146048 match = true;
@@ -6026,10 +6060,12 @@ static bool hist_trigger_check_refs(struct event_trigger_data *data,
60266060 struct hist_trigger_data * hist_data = data -> private_data ;
60276061 struct event_trigger_data * test , * named_data = NULL ;
60286062
6063+ lockdep_assert_held (& event_mutex );
6064+
60296065 if (hist_data -> attrs -> name )
60306066 named_data = find_named_trigger (hist_data -> attrs -> name );
60316067
6032- list_for_each_entry_rcu (test , & file -> triggers , list ) {
6068+ list_for_each_entry (test , & file -> triggers , list ) {
60336069 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
60346070 if (!hist_trigger_match (data , test , named_data , false))
60356071 continue ;
@@ -6051,10 +6087,12 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
60516087 struct event_trigger_data * test , * named_data = NULL ;
60526088 bool unregistered = false;
60536089
6090+ lockdep_assert_held (& event_mutex );
6091+
60546092 if (hist_data -> attrs -> name )
60556093 named_data = find_named_trigger (hist_data -> attrs -> name );
60566094
6057- list_for_each_entry_rcu (test , & file -> triggers , list ) {
6095+ list_for_each_entry (test , & file -> triggers , list ) {
60586096 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
60596097 if (!hist_trigger_match (data , test , named_data , false))
60606098 continue ;
@@ -6080,7 +6118,9 @@ static bool hist_file_check_refs(struct trace_event_file *file)
60806118 struct hist_trigger_data * hist_data ;
60816119 struct event_trigger_data * test ;
60826120
6083- list_for_each_entry_rcu (test , & file -> triggers , list ) {
6121+ lockdep_assert_held (& event_mutex );
6122+
6123+ list_for_each_entry (test , & file -> triggers , list ) {
60846124 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
60856125 hist_data = test -> private_data ;
60866126 if (check_var_refs (hist_data ))
@@ -6323,7 +6363,8 @@ hist_enable_trigger(struct event_trigger_data *data, void *rec,
63236363 struct enable_trigger_data * enable_data = data -> private_data ;
63246364 struct event_trigger_data * test ;
63256365
6326- list_for_each_entry_rcu (test , & enable_data -> file -> triggers , list ) {
6366+ list_for_each_entry_rcu (test , & enable_data -> file -> triggers , list ,
6367+ lockdep_is_held (& event_mutex )) {
63276368 if (test -> cmd_ops -> trigger_type == ETT_EVENT_HIST ) {
63286369 if (enable_data -> enable )
63296370 test -> paused = false;
0 commit comments