| From: Tom Zanussi <tom.zanussi@linux.intel.com> |
| Date: Mon, 15 Jan 2018 20:52:08 -0600 |
| Subject: [PATCH 42/48] tracing: Add a clock attribute for hist triggers |
| |
| The default clock if timestamps are used in a histogram is "global". |
| If timestamps aren't used, the clock is irrelevant. |
| |
| Use the "clock=" param only if you want to override the default |
| "global" clock for a histogram with timestamps. |
| |
| Link: http://lkml.kernel.org/r/427bed1389c5d22aa40c3e0683e30cc3d151e260.1516069914.git.tom.zanussi@linux.intel.com |
| |
| Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> |
| Signed-off-by: Rajvi Jingar <rajvi.jingar@intel.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| (cherry picked from commit 77e7689e0b182465cfcd7c328061b70eecdcde31) |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| Documentation/trace/histogram.txt | 11 +++++++++ |
| kernel/trace/trace_events_hist.c | 42 +++++++++++++++++++++++++++++++++++--- |
| 2 files changed, 49 insertions(+), 4 deletions(-) |
| |
| --- a/Documentation/trace/histogram.txt |
| +++ b/Documentation/trace/histogram.txt |
| @@ -1671,7 +1671,16 @@ specification. In support of this overa |
| it is in units of nanoseconds; appending '.usecs' to a |
| common_timestamp field changes the units to microseconds. |
| |
| -These features are decribed in more detail in the following sections. |
| +A note on inter-event timestamps: If common_timestamp is used in a |
| +histogram, the trace buffer is automatically switched over to using |
| +absolute timestamps and the "global" trace clock, in order to avoid |
| +bogus timestamp differences with other clocks that aren't coherent |
| +across CPUs. This can be overridden by specifying one of the other |
| +trace clocks instead, using the "clock=XXX" hist trigger attribute, |
| +where XXX is any of the clocks listed in the tracing/trace_clock |
| +pseudo-file. |
| + |
| +These features are described in more detail in the following sections. |
| |
| 2.2.1 Histogram Variables |
| ------------------------- |
| --- a/kernel/trace/trace_events_hist.c |
| +++ b/kernel/trace/trace_events_hist.c |
| @@ -242,6 +242,7 @@ struct hist_trigger_attrs { |
| char *vals_str; |
| char *sort_key_str; |
| char *name; |
| + char *clock; |
| bool pause; |
| bool cont; |
| bool clear; |
| @@ -1776,6 +1777,7 @@ static void destroy_hist_trigger_attrs(s |
| kfree(attrs->sort_key_str); |
| kfree(attrs->keys_str); |
| kfree(attrs->vals_str); |
| + kfree(attrs->clock); |
| kfree(attrs); |
| } |
| |
| @@ -1831,6 +1833,19 @@ static int parse_assignment(char *str, s |
| ret = -ENOMEM; |
| goto out; |
| } |
| + } else if (strncmp(str, "clock=", strlen("clock=")) == 0) { |
| + strsep(&str, "="); |
| + if (!str) { |
| + ret = -EINVAL; |
| + goto out; |
| + } |
| + |
| + str = strstrip(str); |
| + attrs->clock = kstrdup(str, GFP_KERNEL); |
| + if (!attrs->clock) { |
| + ret = -ENOMEM; |
| + goto out; |
| + } |
| } else if (strncmp(str, "size=", strlen("size=")) == 0) { |
| int map_bits = parse_map_size(str); |
| |
| @@ -1895,6 +1910,14 @@ static struct hist_trigger_attrs *parse_ |
| goto free; |
| } |
| |
| + if (!attrs->clock) { |
| + attrs->clock = kstrdup("global", GFP_KERNEL); |
| + if (!attrs->clock) { |
| + ret = -ENOMEM; |
| + goto free; |
| + } |
| + } |
| + |
| return attrs; |
| free: |
| destroy_hist_trigger_attrs(attrs); |
| @@ -4936,6 +4959,8 @@ static int event_hist_trigger_print(stru |
| seq_puts(m, ".descending"); |
| } |
| seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits)); |
| + if (hist_data->enable_timestamps) |
| + seq_printf(m, ":clock=%s", hist_data->attrs->clock); |
| |
| print_actions_spec(m, hist_data); |
| |
| @@ -5203,7 +5228,6 @@ static int hist_register_trigger(char *g |
| data->paused = true; |
| |
| if (named_data) { |
| - destroy_hist_data(data->private_data); |
| data->private_data = named_data->private_data; |
| set_named_trigger_data(data, named_data); |
| data->ops = &event_hist_trigger_named_ops; |
| @@ -5215,10 +5239,22 @@ static int hist_register_trigger(char *g |
| goto out; |
| } |
| |
| - ret++; |
| + if (hist_data->enable_timestamps) { |
| + char *clock = hist_data->attrs->clock; |
| + |
| + ret = tracing_set_clock(file->tr, hist_data->attrs->clock); |
| + if (ret) { |
| + hist_err("Couldn't set trace_clock: ", clock); |
| + goto out; |
| + } |
| |
| - if (hist_data->enable_timestamps) |
| tracing_set_time_stamp_abs(file->tr, true); |
| + } |
| + |
| + if (named_data) |
| + destroy_hist_data(hist_data); |
| + |
| + ret++; |
| out: |
| return ret; |
| } |