| From 9127200773678325323ee02d1e962a86937fb111 Mon Sep 17 00:00:00 2001 |
| From: Andi Kleen <ak@linux.intel.com> |
| Date: Fri, 11 Oct 2019 11:21:39 -0700 |
| Subject: [PATCH] perf script: Fix --reltime with --time |
| |
| commit b3509b6ed7a79ec49f6b64e4f3b780f259a2a468 upstream. |
| |
| My earlier patch to just enable --reltime with --time was a little too |
| optimistic. The --time parsing would accept absolute time, which is |
| very confusing to the user. |
| |
| Support relative time in --time parsing too. This only works with recent |
| perf record that records the first sample time. Otherwise we error out. |
| |
| Fixes: 3714437d3fcc ("perf script: Allow --time with --reltime") |
| Signed-off-by: Andi Kleen <ak@linux.intel.com> |
| Cc: Jiri Olsa <jolsa@kernel.org> |
| Link: http://lore.kernel.org/lkml/20191011182140.8353-1-andi@firstfloor.org |
| Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c |
| index be78cb91b8e5..b218c44e7226 100644 |
| --- a/tools/perf/builtin-script.c |
| +++ b/tools/perf/builtin-script.c |
| @@ -3759,10 +3759,11 @@ int cmd_script(int argc, const char **argv) |
| goto out_delete; |
| |
| if (script.time_str) { |
| - err = perf_time__parse_for_ranges(script.time_str, session, |
| + err = perf_time__parse_for_ranges_reltime(script.time_str, session, |
| &script.ptime_range, |
| &script.range_size, |
| - &script.range_num); |
| + &script.range_num, |
| + reltime); |
| if (err < 0) |
| goto out_delete; |
| } |
| diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c |
| index 797dc9e3541b..0bee09661651 100644 |
| --- a/tools/perf/util/time-utils.c |
| +++ b/tools/perf/util/time-utils.c |
| @@ -398,10 +398,11 @@ bool perf_time__ranges_skip_sample(struct perf_time_interval *ptime_buf, |
| return (i == num) ? true : false; |
| } |
| |
| -int perf_time__parse_for_ranges(const char *time_str, |
| +int perf_time__parse_for_ranges_reltime(const char *time_str, |
| struct perf_session *session, |
| struct perf_time_interval **ranges, |
| - int *range_size, int *range_num) |
| + int *range_size, int *range_num, |
| + bool reltime) |
| { |
| bool has_percent = strchr(time_str, '%'); |
| struct perf_time_interval *ptime_range; |
| @@ -411,7 +412,7 @@ int perf_time__parse_for_ranges(const char *time_str, |
| if (!ptime_range) |
| return -ENOMEM; |
| |
| - if (has_percent) { |
| + if (has_percent || reltime) { |
| if (session->evlist->first_sample_time == 0 && |
| session->evlist->last_sample_time == 0) { |
| pr_err("HINT: no first/last sample time found in perf data.\n" |
| @@ -420,7 +421,9 @@ int perf_time__parse_for_ranges(const char *time_str, |
| ret = -EINVAL; |
| goto error; |
| } |
| + } |
| |
| + if (has_percent) { |
| num = perf_time__percent_parse_str( |
| ptime_range, size, |
| time_str, |
| @@ -438,6 +441,15 @@ int perf_time__parse_for_ranges(const char *time_str, |
| num = 1; |
| } |
| |
| + if (reltime) { |
| + int i; |
| + |
| + for (i = 0; i < num; i++) { |
| + ptime_range[i].start += session->evlist->first_sample_time; |
| + ptime_range[i].end += session->evlist->first_sample_time; |
| + } |
| + } |
| + |
| *range_size = size; |
| *range_num = num; |
| *ranges = ptime_range; |
| @@ -448,6 +460,15 @@ int perf_time__parse_for_ranges(const char *time_str, |
| return ret; |
| } |
| |
| +int perf_time__parse_for_ranges(const char *time_str, |
| + struct perf_session *session, |
| + struct perf_time_interval **ranges, |
| + int *range_size, int *range_num) |
| +{ |
| + return perf_time__parse_for_ranges_reltime(time_str, session, ranges, |
| + range_size, range_num, false); |
| +} |
| + |
| int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz) |
| { |
| u64 sec = timestamp / NSEC_PER_SEC; |
| diff --git a/tools/perf/util/time-utils.h b/tools/perf/util/time-utils.h |
| index 72a42ea1d513..e07b698172f5 100644 |
| --- a/tools/perf/util/time-utils.h |
| +++ b/tools/perf/util/time-utils.h |
| @@ -25,6 +25,11 @@ bool perf_time__ranges_skip_sample(struct perf_time_interval *ptime_buf, |
| |
| struct perf_session; |
| |
| +int perf_time__parse_for_ranges_reltime(const char *str, struct perf_session *session, |
| + struct perf_time_interval **ranges, |
| + int *range_size, int *range_num, |
| + bool reltime); |
| + |
| int perf_time__parse_for_ranges(const char *str, struct perf_session *session, |
| struct perf_time_interval **ranges, |
| int *range_size, int *range_num); |
| -- |
| 2.7.4 |
| |