diff --git a/include/tracefs.h b/include/tracefs.h
index 90994de97dda..d83c4e33c69a 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -435,6 +435,13 @@ int tracefs_event_verify_filter(struct tep_event *event, const char *filter,
 #define TRACEFS_TIMESTAMP "common_timestamp"
 #define TRACEFS_TIMESTAMP_USECS "common_timestamp.usecs"
 
+enum tracefs_synth_handler {
+	TRACEFS_SYNTH_HANDLE_NONE	= 0,
+	TRACEFS_SYNTH_HANDLE_MATCH,
+	TRACEFS_SYNTH_HANDLE_MAX,
+	TRACEFS_SYNTH_HANDLE_CHANGE,
+};
+
 struct tracefs_synth *tracefs_synth_init(struct tep_handle *tep,
 					 const char *name,
 					 const char *start_system,
diff --git a/src/tracefs-hist.c b/src/tracefs-hist.c
index 7fffa6cc653d..262db7fbb925 100644
--- a/src/tracefs-hist.c
+++ b/src/tracefs-hist.c
@@ -521,12 +521,25 @@ int tracefs_hist_append_filter(struct tracefs_hist *hist,
 				   type, field, compare, val);
 }
 
+enum action_type {
+	ACTION_NONE,
+	ACTION_TRACE,
+};
+
+struct action {
+	struct action			*next;
+	enum action_type		type;
+	enum tracefs_synth_handler	handler;
+	char				*handle_field;
+};
+
 /*
  * @name: name of the synthetic event
  * @start_system: system of the starting event
  * @start_event: the starting event
  * @end_system: system of the ending event
  * @end_event: the ending event
+ * @actions: List of actions to take
  * @match_names: If a match set is to be a synthetic field, it has a name
  * @start_match: list of keys in the start event that matches end event
  * @end_match: list of keys in the end event that matches the start event
@@ -545,6 +558,8 @@ struct tracefs_synth {
 	struct tep_handle	*tep;
 	struct tep_event	*start_event;
 	struct tep_event	*end_event;
+	struct action		*actions;
+	struct action		**next_action;
 	char			*name;
 	char			**synthetic_fields;
 	char			**synthetic_args;
@@ -575,6 +590,8 @@ struct tracefs_synth {
  */
 void tracefs_synth_free(struct tracefs_synth *synth)
 {
+	struct action *action;
+
 	if (!synth)
 		return;
 
@@ -590,6 +607,12 @@ void tracefs_synth_free(struct tracefs_synth *synth)
 
 	tep_unref(synth->tep);
 
+	while ((action = synth->actions)) {
+		synth->actions = action->next;
+		free(action->handle_field);
+		free(action);
+	}
+
 	free(synth);
 }
 
@@ -750,6 +773,7 @@ synth_init_from(struct tep_handle *tep, const char *start_system,
 		return NULL;
 
 	synth->start_event = start_event;
+	synth->next_action = &synth->actions;
 
 	/* Hold onto a reference to this handler */
 	tep_ref(tep);
@@ -1405,13 +1429,61 @@ static char *create_trace(char *hist, struct tracefs_synth *synth)
 	return append_string(hist, NULL, ")");
 }
 
+static char *create_max(char *hist, struct tracefs_synth *synth, char *field)
+{
+	hist = append_string(hist, NULL, ":onmax(");
+	hist = append_string(hist, NULL, field);
+	return append_string(hist, NULL, ")");
+}
+
+static char *create_change(char *hist, struct tracefs_synth *synth, char *field)
+{
+	hist = append_string(hist, NULL, ":onchange(");
+	hist = append_string(hist, NULL, field);
+	return append_string(hist, NULL, ")");
+}
+
+static char *create_actions(char *hist, struct tracefs_synth *synth)
+{
+	struct action *action;
+
+	if (!synth->actions) {
+		/* Default is "onmatch" and "trace" */
+		hist = create_onmatch(hist, synth);
+		return create_trace(hist, synth);
+	}
+
+	for (action = synth->actions; action; action = action->next) {
+		switch (action->handler) {
+		case TRACEFS_SYNTH_HANDLE_MATCH:
+			hist = create_onmatch(hist, synth);
+			break;
+		case TRACEFS_SYNTH_HANDLE_MAX:
+			hist = create_max(hist, synth, action->handle_field);
+			break;
+		case TRACEFS_SYNTH_HANDLE_CHANGE:
+			hist = create_change(hist, synth, action->handle_field);
+			break;
+		default:
+			continue;
+		}
+		switch (action->type) {
+		case ACTION_TRACE:
+			hist = create_trace(hist, synth);
+			break;
+		default:
+			continue;
+		}
+	}
+	return hist;
+}
+
 static char *create_end_hist(struct tracefs_synth *synth)
 {
 	char *end_hist;
 
 	end_hist = create_hist(synth->end_keys, synth->end_vars);
-	end_hist = create_onmatch(end_hist, synth);
-	return create_trace(end_hist, synth);
+	return create_actions(end_hist, synth);
 }
 
 static char *append_filter(char *hist, char *filter, unsigned int parens)
