perf intel-pt: Add support for PERF_RECORD_SWITCH
Add support for selecting and processing PERF_RECORD_SWITCH events for use by Intel PT. If they are available, they will be used in preference to sched_switch events. This enables an unprivileged user to trace multi-threaded or multi-process workloads with any level of perf_event_paranoid. However it depends on kernel support for PERF_RECORD_SWITCH. Without this patch, tracing a multi-threaded workload will decode without error but all the data will be attributed to the main thread. Without this patch, tracing a multi-process workload will result in decoder errors because the decoder will not know which executable is executing. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/1439458857-30636-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
1b29ac59b1
commit
86c2786994
@@ -624,13 +624,49 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
||||
* threads.
|
||||
*/
|
||||
if (have_timing_info && !cpu_map__empty(cpus)) {
|
||||
err = intel_pt_track_switches(evlist);
|
||||
if (err == -EPERM)
|
||||
pr_debug2("Unable to select sched:sched_switch\n");
|
||||
else if (err)
|
||||
return err;
|
||||
else
|
||||
ptr->have_sched_switch = 1;
|
||||
if (perf_can_record_switch_events()) {
|
||||
bool cpu_wide = !target__none(&opts->target) &&
|
||||
!target__has_task(&opts->target);
|
||||
|
||||
if (!cpu_wide && perf_can_record_cpu_wide()) {
|
||||
struct perf_evsel *switch_evsel;
|
||||
|
||||
err = parse_events(evlist, "dummy:u", NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
switch_evsel = perf_evlist__last(evlist);
|
||||
|
||||
switch_evsel->attr.freq = 0;
|
||||
switch_evsel->attr.sample_period = 1;
|
||||
switch_evsel->attr.context_switch = 1;
|
||||
|
||||
switch_evsel->system_wide = true;
|
||||
switch_evsel->no_aux_samples = true;
|
||||
switch_evsel->immediate = true;
|
||||
|
||||
perf_evsel__set_sample_bit(switch_evsel, TID);
|
||||
perf_evsel__set_sample_bit(switch_evsel, TIME);
|
||||
perf_evsel__set_sample_bit(switch_evsel, CPU);
|
||||
|
||||
opts->record_switch_events = false;
|
||||
ptr->have_sched_switch = 3;
|
||||
} else {
|
||||
opts->record_switch_events = true;
|
||||
if (cpu_wide)
|
||||
ptr->have_sched_switch = 3;
|
||||
else
|
||||
ptr->have_sched_switch = 2;
|
||||
}
|
||||
} else {
|
||||
err = intel_pt_track_switches(evlist);
|
||||
if (err == -EPERM)
|
||||
pr_debug2("Unable to select sched:sched_switch\n");
|
||||
else if (err)
|
||||
return err;
|
||||
else
|
||||
ptr->have_sched_switch = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (intel_pt_evsel) {
|
||||
@@ -663,8 +699,11 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
||||
tracking_evsel->attr.sample_period = 1;
|
||||
|
||||
/* In per-cpu case, always need the time of mmap events etc */
|
||||
if (!cpu_map__empty(cpus))
|
||||
if (!cpu_map__empty(cpus)) {
|
||||
perf_evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
/* And the CPU for switch events */
|
||||
perf_evsel__set_sample_bit(tracking_evsel, CPU);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user