diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2019-11-15 14:42:17 +0200 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-11-22 10:48:13 -0300 |
commit | eb7a52d46c6ac95df563f867d526b3d46616b10b (patch) | |
tree | a5125438d96512fdd938e1618327b929dd566cef /tools/perf/util/auxtrace.c | |
parent | c0a6de06c446f8d173ef53fba361acedd5880b20 (diff) |
perf record: Add aux-sample-size config term
To allow individual events to be selected for AUX area sampling, add
aux-sample-size config term. attr.aux_sample_size is updated by
auxtrace_parse_sample_options() so that the existing validation will see
the value. Any event that has a non-zero aux_sample_size will cause AUX
area sampling to be configured, irrespective of the --aux-sample option.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lore.kernel.org/lkml/20191115124225.5247-8-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/auxtrace.c')
-rw-r--r-- | tools/perf/util/auxtrace.c | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 51fbe01f8a11..026585b67a3c 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -31,6 +31,7 @@ #include "map.h" #include "pmu.h" #include "evsel.h" +#include "evsel_config.h" #include "symbol.h" #include "util/synthetic-events.h" #include "thread_map.h" @@ -76,6 +77,53 @@ static bool perf_evsel__is_aux_event(struct evsel *evsel) return pmu && pmu->auxtrace; } +/* + * Make a group from 'leader' to 'last', requiring that the events were not + * already grouped to a different leader. + */ +static int perf_evlist__regroup(struct evlist *evlist, + struct evsel *leader, + struct evsel *last) +{ + struct evsel *evsel; + bool grp; + + if (!perf_evsel__is_group_leader(leader)) + return -EINVAL; + + grp = false; + evlist__for_each_entry(evlist, evsel) { + if (grp) { + if (!(evsel->leader == leader || + (evsel->leader == evsel && + evsel->core.nr_members <= 1))) + return -EINVAL; + } else if (evsel == leader) { + grp = true; + } + if (evsel == last) + break; + } + + grp = false; + evlist__for_each_entry(evlist, evsel) { + if (grp) { + if (evsel->leader != leader) { + evsel->leader = leader; + if (leader->core.nr_members < 1) + leader->core.nr_members = 1; + leader->core.nr_members += 1; + } + } else if (evsel == leader) { + grp = true; + } + if (evsel == last) + break; + } + + return 0; +} + static bool auxtrace__dont_decode(struct perf_session *session) { return !session->itrace_synth_opts || @@ -679,13 +727,16 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr, struct evlist *evlist, struct record_opts *opts, const char *str) { + struct perf_evsel_config_term *term; + struct evsel *aux_evsel; + bool has_aux_sample_size = false; bool has_aux_leader = false; struct evsel *evsel; char *endptr; unsigned long sz; if (!str) - return 0; + goto no_opt; if (!itr) { pr_err("No AUX area event to sample\n"); @@ -712,6 +763,29 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr, evsel->core.attr.aux_sample_size = sz; } } +no_opt: + aux_evsel = NULL; + /* Override with aux_sample_size from config term */ + evlist__for_each_entry(evlist, evsel) { + if (perf_evsel__is_aux_event(evsel)) + aux_evsel = evsel; + term = perf_evsel__get_config_term(evsel, AUX_SAMPLE_SIZE); + if (term) { + has_aux_sample_size = true; + evsel->core.attr.aux_sample_size = term->val.aux_sample_size; + /* If possible, group with the AUX event */ + if (aux_evsel && evsel->core.attr.aux_sample_size) + perf_evlist__regroup(evlist, aux_evsel, evsel); + } + } + + if (!str && !has_aux_sample_size) + return 0; + + if (!itr) { + pr_err("No AUX area event to sample\n"); + return -EINVAL; + } return auxtrace_validate_aux_sample_size(evlist, opts); } |