perf tools: Add support for PERF_RECORD_AUX_OUTPUT_HW_ID
The PERF_RECORD_AUX_OUTPUT_HW_ID event provides a way to match AUX output data like Intel PT PEBS-via-PT back to the event that it came from, by providing a hardware ID that is present in the AUX output. Reviewed-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Reviewed-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/20210907163903.11820-3-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
70ae034d49
commit
6175047358
@ -1141,6 +1141,21 @@ enum perf_event_type {
|
||||
*/
|
||||
PERF_RECORD_TEXT_POKE = 20,
|
||||
|
||||
/*
|
||||
* Data written to the AUX area by hardware due to aux_output, may need
|
||||
* to be matched to the event by an architecture-specific hardware ID.
|
||||
* This records the hardware ID, but requires sample_id to provide the
|
||||
* event ID. e.g. Intel PT uses this record to disambiguate PEBS-via-PT
|
||||
* records from multiple events.
|
||||
*
|
||||
* struct {
|
||||
* struct perf_event_header header;
|
||||
* u64 hw_id;
|
||||
* struct sample_id sample_id;
|
||||
* };
|
||||
*/
|
||||
PERF_RECORD_AUX_OUTPUT_HW_ID = 21,
|
||||
|
||||
PERF_RECORD_MAX, /* non-ABI */
|
||||
};
|
||||
|
||||
|
@ -289,6 +289,11 @@ struct perf_record_itrace_start {
|
||||
__u32 tid;
|
||||
};
|
||||
|
||||
struct perf_record_aux_output_hw_id {
|
||||
struct perf_event_header header;
|
||||
__u64 hw_id;
|
||||
};
|
||||
|
||||
struct perf_record_thread_map_entry {
|
||||
__u64 pid;
|
||||
char comm[16];
|
||||
@ -414,6 +419,7 @@ union perf_event {
|
||||
struct perf_record_auxtrace_error auxtrace_error;
|
||||
struct perf_record_aux aux;
|
||||
struct perf_record_itrace_start itrace_start;
|
||||
struct perf_record_aux_output_hw_id aux_output_hw_id;
|
||||
struct perf_record_switch context_switch;
|
||||
struct perf_record_thread_map thread_map;
|
||||
struct perf_record_cpu_map cpu_map;
|
||||
|
@ -815,7 +815,8 @@ static int __cmd_inject(struct perf_inject *inject)
|
||||
inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
|
||||
inject->tool.auxtrace = perf_event__process_auxtrace;
|
||||
inject->tool.aux = perf_event__drop_aux;
|
||||
inject->tool.itrace_start = perf_event__drop_aux,
|
||||
inject->tool.itrace_start = perf_event__drop_aux;
|
||||
inject->tool.aux_output_hw_id = perf_event__drop_aux;
|
||||
inject->tool.ordered_events = true;
|
||||
inject->tool.ordering_requires_timestamps = true;
|
||||
/* Allow space in the header for new attributes */
|
||||
@ -882,6 +883,7 @@ int cmd_inject(int argc, const char **argv)
|
||||
.lost_samples = perf_event__repipe,
|
||||
.aux = perf_event__repipe,
|
||||
.itrace_start = perf_event__repipe,
|
||||
.aux_output_hw_id = perf_event__repipe,
|
||||
.context_switch = perf_event__repipe,
|
||||
.throttle = perf_event__repipe,
|
||||
.unthrottle = perf_event__repipe,
|
||||
|
@ -1411,7 +1411,7 @@ static int record__synthesize(struct record *rec, bool tail)
|
||||
goto out;
|
||||
|
||||
/* Synthesize id_index before auxtrace_info */
|
||||
if (rec->opts.auxtrace_sample_mode) {
|
||||
if (rec->opts.auxtrace_sample_mode || rec->opts.full_auxtrace) {
|
||||
err = perf_event__synthesize_id_index(tool,
|
||||
process_synthesized_event,
|
||||
session->evlist, machine);
|
||||
|
@ -57,6 +57,7 @@ static const char *perf_event__names[] = {
|
||||
[PERF_RECORD_BPF_EVENT] = "BPF_EVENT",
|
||||
[PERF_RECORD_CGROUP] = "CGROUP",
|
||||
[PERF_RECORD_TEXT_POKE] = "TEXT_POKE",
|
||||
[PERF_RECORD_AUX_OUTPUT_HW_ID] = "AUX_OUTPUT_HW_ID",
|
||||
[PERF_RECORD_HEADER_ATTR] = "ATTR",
|
||||
[PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE",
|
||||
[PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA",
|
||||
@ -237,6 +238,14 @@ int perf_event__process_itrace_start(struct perf_tool *tool __maybe_unused,
|
||||
return machine__process_itrace_start_event(machine, event);
|
||||
}
|
||||
|
||||
int perf_event__process_aux_output_hw_id(struct perf_tool *tool __maybe_unused,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
struct machine *machine)
|
||||
{
|
||||
return machine__process_aux_output_hw_id_event(machine, event);
|
||||
}
|
||||
|
||||
int perf_event__process_lost_samples(struct perf_tool *tool __maybe_unused,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
@ -407,6 +416,12 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
|
||||
event->itrace_start.pid, event->itrace_start.tid);
|
||||
}
|
||||
|
||||
size_t perf_event__fprintf_aux_output_hw_id(union perf_event *event, FILE *fp)
|
||||
{
|
||||
return fprintf(fp, " hw_id: %#"PRI_lx64"\n",
|
||||
event->aux_output_hw_id.hw_id);
|
||||
}
|
||||
|
||||
size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp)
|
||||
{
|
||||
bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
|
||||
@ -534,6 +549,9 @@ size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FIL
|
||||
case PERF_RECORD_TEXT_POKE:
|
||||
ret += perf_event__fprintf_text_poke(event, machine, fp);
|
||||
break;
|
||||
case PERF_RECORD_AUX_OUTPUT_HW_ID:
|
||||
ret += perf_event__fprintf_aux_output_hw_id(event, fp);
|
||||
break;
|
||||
default:
|
||||
ret += fprintf(fp, "\n");
|
||||
}
|
||||
|
@ -330,6 +330,10 @@ int perf_event__process_itrace_start(struct perf_tool *tool,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct machine *machine);
|
||||
int perf_event__process_aux_output_hw_id(struct perf_tool *tool,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct machine *machine);
|
||||
int perf_event__process_switch(struct perf_tool *tool,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
@ -397,6 +401,7 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_aux_output_hw_id(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);
|
||||
size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp);
|
||||
|
@ -755,6 +755,14 @@ int machine__process_itrace_start_event(struct machine *machine __maybe_unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int machine__process_aux_output_hw_id_event(struct machine *machine __maybe_unused,
|
||||
union perf_event *event)
|
||||
{
|
||||
if (dump_trace)
|
||||
perf_event__fprintf_aux_output_hw_id(event, stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int machine__process_switch_event(struct machine *machine __maybe_unused,
|
||||
union perf_event *event)
|
||||
{
|
||||
@ -2028,6 +2036,8 @@ int machine__process_event(struct machine *machine, union perf_event *event,
|
||||
ret = machine__process_bpf(machine, event, sample); break;
|
||||
case PERF_RECORD_TEXT_POKE:
|
||||
ret = machine__process_text_poke(machine, event, sample); break;
|
||||
case PERF_RECORD_AUX_OUTPUT_HW_ID:
|
||||
ret = machine__process_aux_output_hw_id_event(machine, event); break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
|
@ -124,6 +124,8 @@ int machine__process_aux_event(struct machine *machine,
|
||||
union perf_event *event);
|
||||
int machine__process_itrace_start_event(struct machine *machine,
|
||||
union perf_event *event);
|
||||
int machine__process_aux_output_hw_id_event(struct machine *machine,
|
||||
union perf_event *event);
|
||||
int machine__process_switch_event(struct machine *machine,
|
||||
union perf_event *event);
|
||||
int machine__process_namespaces_event(struct machine *machine,
|
||||
|
@ -509,6 +509,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
|
||||
tool->bpf = perf_event__process_bpf;
|
||||
if (tool->text_poke == NULL)
|
||||
tool->text_poke = perf_event__process_text_poke;
|
||||
if (tool->aux_output_hw_id == NULL)
|
||||
tool->aux_output_hw_id = perf_event__process_aux_output_hw_id;
|
||||
if (tool->read == NULL)
|
||||
tool->read = process_event_sample_stub;
|
||||
if (tool->throttle == NULL)
|
||||
@ -1000,6 +1002,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
|
||||
[PERF_RECORD_NAMESPACES] = perf_event__namespaces_swap,
|
||||
[PERF_RECORD_CGROUP] = perf_event__cgroup_swap,
|
||||
[PERF_RECORD_TEXT_POKE] = perf_event__text_poke_swap,
|
||||
[PERF_RECORD_AUX_OUTPUT_HW_ID] = perf_event__all64_swap,
|
||||
[PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
|
||||
[PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
|
||||
[PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
|
||||
@ -1556,6 +1559,8 @@ static int machines__deliver_event(struct machines *machines,
|
||||
return tool->bpf(tool, event, sample, machine);
|
||||
case PERF_RECORD_TEXT_POKE:
|
||||
return tool->text_poke(tool, event, sample, machine);
|
||||
case PERF_RECORD_AUX_OUTPUT_HW_ID:
|
||||
return tool->aux_output_hw_id(tool, event, sample, machine);
|
||||
default:
|
||||
++evlist->stats.nr_unknown_events;
|
||||
return -1;
|
||||
|
@ -53,6 +53,7 @@ struct perf_tool {
|
||||
lost_samples,
|
||||
aux,
|
||||
itrace_start,
|
||||
aux_output_hw_id,
|
||||
context_switch,
|
||||
throttle,
|
||||
unthrottle,
|
||||
|
Loading…
Reference in New Issue
Block a user