From: Adrian Hunter <adrian.hun...@intel.com>

Process synth_opts.other_events and attr.aux_output to set up for
synthesizing PEBs via Intel PT events.

Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
Cc: Jiri Olsa <jo...@kernel.org>
Cc: Kan Liang <kan.li...@linux.intel.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: 
http://lkml.kernel.org/r/20190806084606.4021-6-alexander.shish...@linux.intel.com
Signed-off-by: Alexander Shishkin <alexander.shish...@linux.intel.com>
[ Fixed up libbperf clashes, i.e. some places using perf_evsel (now in libperf)
  need to use instead 'evsel' (a tools/perf only abstraction) ]
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/arch/x86/util/intel-pt.c | 23 +++++++++++++++++++++++
 tools/perf/util/intel-pt.c          | 18 ++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/tools/perf/arch/x86/util/intel-pt.c 
b/tools/perf/arch/x86/util/intel-pt.c
index 218a4e694618..a8e633aa278a 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -548,6 +548,26 @@ static int intel_pt_validate_config(struct perf_pmu 
*intel_pt_pmu,
                                        evsel->core.attr.config);
 }
 
+/*
+ * Currently, there is not enough information to disambiguate different PEBS
+ * events, so only allow one.
+ */
+static bool intel_pt_too_many_aux_output(struct evlist *evlist)
+{
+       struct evsel *evsel;
+       int aux_output_cnt = 0;
+
+       evlist__for_each_entry(evlist, evsel)
+               aux_output_cnt += !!evsel->core.attr.aux_output;
+
+       if (aux_output_cnt > 1) {
+               pr_err(INTEL_PT_PMU_NAME " supports at most one event with 
aux-output\n");
+               return true;
+       }
+
+       return false;
+}
+
 static int intel_pt_recording_options(struct auxtrace_record *itr,
                                      struct evlist *evlist,
                                      struct record_opts *opts)
@@ -588,6 +608,9 @@ static int intel_pt_recording_options(struct 
auxtrace_record *itr,
                return -EINVAL;
        }
 
+       if (intel_pt_too_many_aux_output(evlist))
+               return -EINVAL;
+
        if (!opts->full_auxtrace)
                return 0;
 
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 4c52204868d8..ea504fa9b623 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -2894,6 +2894,22 @@ static int intel_pt_synth_events(struct intel_pt *pt,
        return 0;
 }
 
+static void intel_pt_setup_pebs_events(struct intel_pt *pt)
+{
+       struct evsel *evsel;
+
+       if (!pt->synth_opts.other_events)
+               return;
+
+       evlist__for_each_entry(pt->session->evlist, evsel) {
+               if (evsel->core.attr.aux_output && evsel->id) {
+                       pt->sample_pebs = true;
+                       pt->pebs_evsel = evsel;
+                       return;
+               }
+       }
+}
+
 static struct evsel *intel_pt_find_sched_switch(struct evlist *evlist)
 {
        struct evsel *evsel;
@@ -3263,6 +3279,8 @@ int intel_pt_process_auxtrace_info(union perf_event 
*event,
        if (err)
                goto err_delete_thread;
 
+       intel_pt_setup_pebs_events(pt);
+
        err = auxtrace_queues__process_index(&pt->queues, session);
        if (err)
                goto err_delete_thread;
-- 
2.21.0

Reply via email to