107 lines
3.3 KiB
Diff
107 lines
3.3 KiB
Diff
From: Tom Zanussi <tom.zanussi@linux.intel.com>
|
|
Date: Mon, 26 Jun 2017 17:49:29 -0500
|
|
Subject: [PATCH 28/32] tracing: Add hist trigger support for variable
|
|
reference aliases
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.11/older/patches-4.11.8-rt5.tar.xz
|
|
|
|
Add support for alias=$somevar where alias can be used as
|
|
onmatch($alias).
|
|
|
|
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
kernel/trace/trace_events_hist.c | 46 ++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 43 insertions(+), 3 deletions(-)
|
|
|
|
--- a/kernel/trace/trace_events_hist.c
|
|
+++ b/kernel/trace/trace_events_hist.c
|
|
@@ -225,6 +225,7 @@ enum hist_field_flags {
|
|
HIST_FIELD_FL_EXPR = 16384,
|
|
HIST_FIELD_FL_VAR_REF = 32768,
|
|
HIST_FIELD_FL_CPU = 65536,
|
|
+ HIST_FIELD_FL_ALIAS = 131072,
|
|
};
|
|
|
|
struct hist_trigger_attrs {
|
|
@@ -1414,7 +1415,8 @@ static const char *hist_field_name(struc
|
|
|
|
if (field->field)
|
|
field_name = field->field->name;
|
|
- else if (field->flags & HIST_FIELD_FL_LOG2)
|
|
+ else if (field->flags & HIST_FIELD_FL_LOG2 ||
|
|
+ field->flags & HIST_FIELD_FL_ALIAS)
|
|
field_name = hist_field_name(field->operands[0], ++level);
|
|
else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
|
|
field_name = "$common_timestamp";
|
|
@@ -1819,7 +1821,7 @@ static struct hist_field *create_hist_fi
|
|
|
|
hist_field->hist_data = hist_data;
|
|
|
|
- if (flags & HIST_FIELD_FL_EXPR)
|
|
+ if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS)
|
|
goto out; /* caller will populate */
|
|
|
|
if (flags & HIST_FIELD_FL_VAR_REF) {
|
|
@@ -2013,6 +2015,34 @@ parse_field(struct hist_trigger_data *hi
|
|
return field;
|
|
}
|
|
|
|
+static struct hist_field *create_alias(struct hist_trigger_data *hist_data,
|
|
+ struct hist_field *var_ref,
|
|
+ char *var_name)
|
|
+{
|
|
+ struct hist_field *alias = NULL;
|
|
+ unsigned long flags = HIST_FIELD_FL_ALIAS | HIST_FIELD_FL_VAR |
|
|
+ HIST_FIELD_FL_VAR_ONLY;
|
|
+
|
|
+ alias = create_hist_field(hist_data, NULL, flags, var_name);
|
|
+ if (!alias)
|
|
+ return NULL;
|
|
+
|
|
+ alias->fn = var_ref->fn;
|
|
+ alias->operands[0] = var_ref;
|
|
+ alias->var.idx = var_ref->var.idx;
|
|
+ alias->var.hist_data = var_ref->hist_data;
|
|
+ alias->size = var_ref->size;
|
|
+ alias->is_signed = var_ref->is_signed;
|
|
+ alias->type = kstrdup(var_ref->type, GFP_KERNEL);
|
|
+ if (!alias->type) {
|
|
+ kfree(alias->type);
|
|
+ destroy_hist_field(alias, 0);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return alias;
|
|
+}
|
|
+
|
|
struct hist_field *parse_atom(struct hist_trigger_data *hist_data,
|
|
struct trace_event_file *file, char *str,
|
|
unsigned long *flags, char *var_name)
|
|
@@ -2036,6 +2066,13 @@ struct hist_field *parse_atom(struct his
|
|
if (hist_field) {
|
|
hist_data->var_refs[hist_data->n_var_refs] = hist_field;
|
|
hist_field->var_ref_idx = hist_data->n_var_refs++;
|
|
+ if (var_name) {
|
|
+ hist_field = create_alias(hist_data, hist_field, var_name);
|
|
+ if (!hist_field) {
|
|
+ ret = -ENOMEM;
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
return hist_field;
|
|
}
|
|
|
|
@@ -4152,8 +4189,11 @@ static void hist_field_print(struct seq_
|
|
seq_puts(m, "$common_timestamp");
|
|
else if (hist_field->flags & HIST_FIELD_FL_CPU)
|
|
seq_puts(m, "cpu");
|
|
- else if (field_name)
|
|
+ else if (field_name) {
|
|
+ if (hist_field->flags & HIST_FIELD_FL_ALIAS)
|
|
+ seq_putc(m, '$');
|
|
seq_printf(m, "%s", field_name);
|
|
+ }
|
|
|
|
if (hist_field->flags) {
|
|
const char *flags_str = get_hist_field_flags(hist_field);
|