Hi Tom, On Wed, Nov 14, 2018 at 02:18:02PM -0600, Tom Zanussi wrote: > From: Tom Zanussi <tom.zanussi@xxxxxxxxxxxxxxx> > > The action refactor code allowed actions and handlers to be separated, > but the existing onmax handler and save action code is still not > flexible enough to handle arbitrary coupling. This change generalizes > them and in the process makes additional handlers and actions easier > to implement. > > The onmax action can be broken up and thought of as two separate > components - a variable to be tracked (the parameter given to the > onmax($var_to_track) function) and an invisible variable created to > save the ongoing result of doing something with that variable, such as > saving the max value of that variable so far seen. > > Separating it out like this and renaming it appropriately allows us to > use the same code for similar tracking functions such as > onchange($var_to_track), which would just track the last value seen > rather than the max seen so far, which is useful in some situations. > > Additionally, because different handlers and actions may want to save > and access data differently e.g. save and retrieve tracking values as > local variables vs something more global, save_val() and get_val() > interface functions are introduced and max-specific implementations > are used instead. > > The same goes for the code that checks whether a maximum has been hit > - a generic check_val() interface and max-checking implementation is > used instead, which allows future patches to make use of he same code > using their own implemetations of similar functionality. > > Signed-off-by: Tom Zanussi <tom.zanussi@xxxxxxxxxxxxxxx> > --- > kernel/trace/trace_events_hist.c | 225 ++++++++++++++++++++++++++------------- > 1 file changed, 151 insertions(+), 74 deletions(-) > > diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c > index 54b78cfe2766..ac48ad1482c8 100644 > --- a/kernel/trace/trace_events_hist.c > +++ b/kernel/trace/trace_events_hist.c > @@ -319,6 +319,15 @@ typedef void (*action_fn_t) (struct hist_trigger_data *hist_data, > struct ring_buffer_event *rbe, > struct action_data *data, u64 *var_ref_vals); > > +typedef bool (*check_track_val_fn_t) (u64 track_val, u64 var_val); > +typedef bool (*save_track_val_fn_t) (struct hist_trigger_data *hist_data, > + struct tracing_map_elt *elt, > + struct action_data *data, > + unsigned int track_var_idx, u64 var_val); > +typedef u64 (*get_track_val_fn_t) (struct hist_trigger_data *hist_data, > + struct tracing_map_elt *elt, > + struct action_data *data); > + > enum handler_id { > HANDLER_ONMATCH = 1, > HANDLER_ONMAX, > @@ -349,14 +358,18 @@ struct action_data { > > struct { > char *var_str; > - unsigned int max_var_ref_idx; > - struct hist_field *max_var; > - struct hist_field *var; > - } onmax; > + struct hist_field *var_ref; > + unsigned int var_ref_idx; I have a question. It's confusing for me there are many indexes for a variable (ref). The hist_field already has var.idx, var_idx and var_ref_idx in it. But you also added an external var_ref_idx along with the var_ref. Also I see another var_ref_idx in the action data. Is all that really needed? Could you please add some comment then? Thanks, Namhyung > + > + struct hist_field *track_var; > + > + check_track_val_fn_t check_val; > + save_track_val_fn_t save_val; > + get_track_val_fn_t get_val; > + } track_data; > }; > };