summaryrefslogtreecommitdiff
path: root/tools/perf/util/auxtrace.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2019-11-15 14:42:17 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-11-22 10:48:13 -0300
commiteb7a52d46c6ac95df563f867d526b3d46616b10b (patch)
treea5125438d96512fdd938e1618327b929dd566cef /tools/perf/util/auxtrace.c
parentc0a6de06c446f8d173ef53fba361acedd5880b20 (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.c76
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);
}