From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Tom Zanussi <tom.zanussi@linux.intel.com>
Subject: [for-next][PATCH 21/29] tracing: Add hist trigger onchange() handler
Date: Wed, 20 Feb 2019 13:37:58 -0500 [thread overview]
Message-ID: <20190220183807.288886701@goodmis.org> (raw)
In-Reply-To: 20190220183737.034634614@goodmis.org
From: Tom Zanussi <tom.zanussi@linux.intel.com>
Add support for a hist:onchange($var) handler, similar to the onmax()
handler but triggering whenever there's any change in $var, not just a
max.
Link: http://lkml.kernel.org/r/dfbc7e4ada242603e9ec3f049b5ad076a07dfd03.1550100284.git.tom.zanussi@linux.intel.com
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
kernel/trace/trace.c | 3 +-
kernel/trace/trace_events_hist.c | 58 +++++++++++++++++++++++++++-----
2 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index dd60c14a0fb0..be6779f963c6 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4915,7 +4915,8 @@ static const char readme_msg[] =
"\t <handler>.<action>\n\n"
"\t The available handlers are:\n\n"
"\t onmatch(matching.event) - invoke on addition or update\n"
- "\t onmax(var) - invoke if var exceeds current max\n\n"
+ "\t onmax(var) - invoke if var exceeds current max\n"
+ "\t onchange(var) - invoke action if var changes\n\n"
"\t The available actions are:\n\n"
"\t <synthetic_event>(param list) - generate synthetic event\n"
"\t save(field,...) - save current event fields\n"
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 571937a268a3..2f3323ca9d24 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -391,6 +391,7 @@ typedef bool (*check_track_val_fn_t) (u64 track_val, u64 var_val);
enum handler_id {
HANDLER_ONMATCH = 1,
HANDLER_ONMAX,
+ HANDLER_ONCHANGE,
};
enum action_id {
@@ -1989,7 +1990,8 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs)
return ret;
if ((str_has_prefix(str, "onmatch(")) ||
- (str_has_prefix(str, "onmax("))) {
+ (str_has_prefix(str, "onmax(")) ||
+ (str_has_prefix(str, "onchange("))) {
attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
if (!attrs->action_str[attrs->n_actions]) {
ret = -ENOMEM;
@@ -3481,6 +3483,14 @@ static bool check_track_val_max(u64 track_val, u64 var_val)
return true;
}
+static bool check_track_val_changed(u64 track_val, u64 var_val)
+{
+ if (var_val == track_val)
+ return false;
+
+ return true;
+}
+
static u64 get_track_val(struct hist_trigger_data *hist_data,
struct tracing_map_elt *elt,
struct action_data *data)
@@ -3640,6 +3650,8 @@ static void track_data_print(struct seq_file *m,
if (data->handler == HANDLER_ONMAX)
seq_printf(m, "\n\tmax: %10llu", track_val);
+ else if (data->handler == HANDLER_ONCHANGE)
+ seq_printf(m, "\n\tchanged: %10llu", track_val);
if (data->action == ACTION_SNAPSHOT)
return;
@@ -3727,14 +3739,14 @@ static int track_data_create(struct hist_trigger_data *hist_data,
track_data_var_str = data->track_data.var_str;
if (track_data_var_str[0] != '$') {
- hist_err("For onmax(x), x must be a variable: ", track_data_var_str);
+ hist_err("For onmax(x) or onchange(x), x must be a variable: ", track_data_var_str);
return -EINVAL;
}
track_data_var_str++;
var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str);
if (!var_field) {
- hist_err("Couldn't find onmax variable: ", track_data_var_str);
+ hist_err("Couldn't find onmax or onchange variable: ", track_data_var_str);
return -EINVAL;
}
@@ -3751,6 +3763,14 @@ static int track_data_create(struct hist_trigger_data *hist_data,
ret = PTR_ERR(track_var);
goto out;
}
+
+ if (data->handler == HANDLER_ONCHANGE)
+ track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64");
+ if (IS_ERR(track_var)) {
+ hist_err("Couldn't create onchange variable: ", "__change");
+ ret = PTR_ERR(track_var);
+ goto out;
+ }
data->track_data.track_var = track_var;
ret = action_create(hist_data, data);
@@ -3830,6 +3850,8 @@ static int action_parse(char *str, struct action_data *data,
if (handler == HANDLER_ONMAX)
data->track_data.check_val = check_track_val_max;
+ else if (handler == HANDLER_ONCHANGE)
+ data->track_data.check_val = check_track_val_changed;
else {
hist_err("action parsing: Handler doesn't support action: ", action_name);
ret = -EINVAL;
@@ -3850,6 +3872,8 @@ static int action_parse(char *str, struct action_data *data,
if (handler == HANDLER_ONMAX)
data->track_data.check_val = check_track_val_max;
+ else if (handler == HANDLER_ONCHANGE)
+ data->track_data.check_val = check_track_val_changed;
else {
hist_err("action parsing: Handler doesn't support action: ", action_name);
ret = -EINVAL;
@@ -3870,6 +3894,8 @@ static int action_parse(char *str, struct action_data *data,
if (handler == HANDLER_ONMAX)
data->track_data.check_val = check_track_val_max;
+ else if (handler == HANDLER_ONCHANGE)
+ data->track_data.check_val = check_track_val_changed;
if (handler != HANDLER_ONMATCH) {
data->track_data.save_data = action_trace;
@@ -4700,7 +4726,8 @@ static void destroy_actions(struct hist_trigger_data *hist_data)
if (data->handler == HANDLER_ONMATCH)
onmatch_destroy(data);
- else if (data->handler == HANDLER_ONMAX)
+ else if (data->handler == HANDLER_ONMAX ||
+ data->handler == HANDLER_ONCHANGE)
track_data_destroy(hist_data, data);
else
kfree(data);
@@ -4736,6 +4763,15 @@ static int parse_actions(struct hist_trigger_data *hist_data)
ret = PTR_ERR(data);
break;
}
+ } else if ((len = str_has_prefix(str, "onchange("))) {
+ char *action_str = str + len;
+
+ data = track_data_parse(hist_data, action_str,
+ HANDLER_ONCHANGE);
+ if (IS_ERR(data)) {
+ ret = PTR_ERR(data);
+ break;
+ }
} else {
ret = -EINVAL;
break;
@@ -4760,7 +4796,8 @@ static int create_actions(struct hist_trigger_data *hist_data)
ret = onmatch_create(hist_data, data);
if (ret)
break;
- } else if (data->handler == HANDLER_ONMAX) {
+ } else if (data->handler == HANDLER_ONMAX ||
+ data->handler == HANDLER_ONCHANGE) {
ret = track_data_create(hist_data, data);
if (ret)
break;
@@ -4785,7 +4822,8 @@ static void print_actions(struct seq_file *m,
if (data->action == ACTION_SNAPSHOT)
continue;
- if (data->handler == HANDLER_ONMAX)
+ if (data->handler == HANDLER_ONMAX ||
+ data->handler == HANDLER_ONCHANGE)
track_data_print(m, hist_data, elt, data);
}
}
@@ -4817,6 +4855,8 @@ static void print_track_data_spec(struct seq_file *m,
{
if (data->handler == HANDLER_ONMAX)
seq_puts(m, ":onmax(");
+ else if (data->handler == HANDLER_ONCHANGE)
+ seq_puts(m, ":onchange(");
seq_printf(m, "%s", data->track_data.var_str);
seq_printf(m, ").%s(", data->action_name);
@@ -4874,7 +4914,8 @@ static bool actions_match(struct hist_trigger_data *hist_data,
if (strcmp(data->match_data.event,
data_test->match_data.event) != 0)
return false;
- } else if (data->handler == HANDLER_ONMAX) {
+ } else if (data->handler == HANDLER_ONMAX ||
+ data->handler == HANDLER_ONCHANGE) {
if (strcmp(data->track_data.var_str,
data_test->track_data.var_str) != 0)
return false;
@@ -4895,7 +4936,8 @@ static void print_actions_spec(struct seq_file *m,
if (data->handler == HANDLER_ONMATCH)
print_onmatch_spec(m, hist_data, data);
- else if (data->handler == HANDLER_ONMAX)
+ else if (data->handler == HANDLER_ONMAX ||
+ data->handler == HANDLER_ONCHANGE)
print_track_data_spec(m, hist_data, data);
}
}
--
2.20.1
next prev parent reply other threads:[~2019-02-20 18:39 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-20 18:37 [for-next][PATCH 00/29] tracing: Updates for 5.1 Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 01/29] function_graph: Support displaying relative timestamp Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 02/29] tracing: Annotate implicit fall through in parse_probe_arg() Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 03/29] tracing: Annotate implicit fall through in predicate_parse() Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 04/29] tracing: Add comment to predicate_parse() about "&&" or "||" Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 05/29] tracing: Show more info for funcgraph wakeup tracers Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 06/29] tracing: Put a margin between flags and duration for " Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 07/29] tracing/doc: Add latency tracer funcgraph example Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 08/29] tracing: Show stacktrace for wakeup tracers Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 09/29] ring-buffer: Remove unused function ring_buffer_page_len() Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 10/29] tracing: Change the function format to display function names by perf Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 11/29] ftrace: Allow enabling of filters via index of available_filter_functions Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 12/29] uprobes: convert uprobe.ref to refcount_t Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 13/29] tracing: No need to free iter->trace in fail path of tracing_open_pipe() Steven Rostedt
2019-02-20 18:46 ` Steven Rostedt
2019-02-20 18:50 ` Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 14/29] tracing: Refactor hist trigger action code Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 15/29] tracing: Make hist trigger Documentation better reflect actions/handlers Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 16/29] tracing: Split up onmatch action data Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 17/29] tracing: Generalize hist trigger onmax and save action Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 18/29] tracing: Add conditional snapshot Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 19/29] tracing: Add hist trigger snapshot() action Steven Rostedt
2019-02-20 18:37 ` [for-next][PATCH 20/29] tracing: Add hist trigger snapshot() action Documentation Steven Rostedt
2019-02-20 18:37 ` Steven Rostedt [this message]
2019-02-20 18:37 ` [for-next][PATCH 22/29] tracing: Add hist trigger onchange() handler Documentation Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 23/29] tracing: Add alternative synthetic event trace action syntax Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 24/29] tracing: Add SPDX license GPL-2.0 license identifier to inter-event testcases Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 25/29] tracing: Add hist trigger snapshot() action test case Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 26/29] tracing: Add hist trigger onchange() handler " Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 27/29] tracing: Add alternative synthetic event trace action " Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 28/29] tracing: Add hist trigger action expected fail " Steven Rostedt
2019-02-20 18:38 ` [for-next][PATCH 29/29] tracing: Comment why cond_snapshot is checked outside of max_lock protection Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190220183807.288886701@goodmis.org \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=tom.zanussi@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.