From 4a96f7a02eb52b1b618ab610e689bd82770f00b0 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 30 Apr 2015 17:37:29 +0300 Subject: [PATCH] perf tools: Add support for PERF_RECORD_AUX Add support for the PERF_RECORD_AUX event type. PERF_RECORD_AUX is a new kernel event that records when new data lands in the AUX buffer. Currently it is assumed that AUX data follows the same ring buffer conventions used by the perf events buffer, and consequently the AUX event is not processed during recording. It is processed during session processing so that the information in the 'flags' member is made available. The format of PERF_RECORD_AUX is outlined in the linux/perf_events.h header file. The 'flags' are also enumerated. Intel PT and Intel BTS use the flag named PERF_AUX_FLAG_TRUNCATED to determine if data has been lost because the buffer became full as perf was not able to empty it fast enough. Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1430404667-10593-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 1 + tools/perf/util/event.c | 21 +++++++++++++++++++++ tools/perf/util/event.h | 13 +++++++++++++ tools/perf/util/machine.c | 10 ++++++++++ tools/perf/util/machine.h | 2 ++ tools/perf/util/session.c | 15 +++++++++++++++ tools/perf/util/tool.h | 1 + 7 files changed, 63 insertions(+) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 7c7a7eea900d..3e8f730c7dee 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -558,6 +558,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .fork = perf_event__repipe, .exit = perf_event__repipe, .lost = perf_event__repipe, + .aux = perf_event__repipe, .read = perf_event__repipe_sample, .throttle = perf_event__repipe, .unthrottle = perf_event__repipe, diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 32323e5d7b25..724ffde8e7d7 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -23,6 +23,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_FORK] = "FORK", [PERF_RECORD_READ] = "READ", [PERF_RECORD_SAMPLE] = "SAMPLE", + [PERF_RECORD_AUX] = "AUX", [PERF_RECORD_HEADER_ATTR] = "ATTR", [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", @@ -695,6 +696,14 @@ int perf_event__process_lost(struct perf_tool *tool __maybe_unused, return machine__process_lost_event(machine, event, sample); } +int perf_event__process_aux(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine) +{ + return machine__process_aux_event(machine, event); +} + size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) { return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", @@ -758,6 +767,15 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused, return machine__process_exit_event(machine, event, sample); } +size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp) +{ + return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n", + event->aux.aux_offset, event->aux.aux_size, + event->aux.flags, + event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "", + event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : ""); +} + size_t perf_event__fprintf(union perf_event *event, FILE *fp) { size_t ret = fprintf(fp, "PERF_RECORD_%s", @@ -777,6 +795,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) case PERF_RECORD_MMAP2: ret += perf_event__fprintf_mmap2(event, fp); break; + case PERF_RECORD_AUX: + ret += perf_event__fprintf_aux(event, fp); + break; default: ret += fprintf(fp, "\n"); } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 80e9f5969a39..b3c350ed4768 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -323,6 +323,13 @@ struct auxtrace_error_event { char msg[MAX_AUXTRACE_ERROR_MSG]; }; +struct aux_event { + struct perf_event_header header; + u64 aux_offset; + u64 aux_size; + u64 flags; +}; + union perf_event { struct perf_event_header header; struct mmap_event mmap; @@ -341,6 +348,7 @@ union perf_event { struct auxtrace_info_event auxtrace_info; struct auxtrace_event auxtrace; struct auxtrace_error_event auxtrace_error; + struct aux_event aux; }; void perf_event__print_totals(void); @@ -376,6 +384,10 @@ int perf_event__process_lost(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); +int perf_event__process_aux(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine); int perf_event__process_mmap(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -433,6 +445,7 @@ size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); 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(union perf_event *event, FILE *fp); u64 kallsyms__get_function_start(const char *kallsyms_filename, diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 527e032e24f6..a7ad51100b55 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -486,6 +486,14 @@ machine__module_dso(struct machine *machine, struct kmod_path *m, return dso; } +int machine__process_aux_event(struct machine *machine __maybe_unused, + union perf_event *event) +{ + if (dump_trace) + perf_event__fprintf_aux(event, stdout); + return 0; +} + struct map *machine__new_module(struct machine *machine, u64 start, const char *filename) { @@ -1331,6 +1339,8 @@ int machine__process_event(struct machine *machine, union perf_event *event, ret = machine__process_exit_event(machine, event, sample); break; case PERF_RECORD_LOST: ret = machine__process_lost_event(machine, event, sample); break; + case PERF_RECORD_AUX: + ret = machine__process_aux_event(machine, event); break; default: ret = -1; break; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 6d64cedb9d1e..fc5432aa66b5 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -81,6 +81,8 @@ int machine__process_fork_event(struct machine *machine, union perf_event *event struct perf_sample *sample); int machine__process_lost_event(struct machine *machine, union perf_event *event, struct perf_sample *sample); +int machine__process_aux_event(struct machine *machine, + union perf_event *event); int machine__process_mmap_event(struct machine *machine, union perf_event *event, struct perf_sample *sample); int machine__process_mmap2_event(struct machine *machine, union perf_event *event, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b6972b118bc2..0b4646cd5245 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -325,6 +325,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->exit = process_event_stub; if (tool->lost == NULL) tool->lost = perf_event__process_lost; + if (tool->aux == NULL) + tool->aux = perf_event__process_aux; if (tool->read == NULL) tool->read = process_event_sample_stub; if (tool->throttle == NULL) @@ -443,6 +445,16 @@ static void perf_event__read_swap(union perf_event *event, bool sample_id_all) swap_sample_id_all(event, &event->read + 1); } +static void perf_event__aux_swap(union perf_event *event, bool sample_id_all) +{ + event->aux.aux_offset = bswap_64(event->aux.aux_offset); + event->aux.aux_size = bswap_64(event->aux.aux_size); + event->aux.flags = bswap_64(event->aux.flags); + + if (sample_id_all) + swap_sample_id_all(event, &event->aux + 1); +} + static void perf_event__throttle_swap(union perf_event *event, bool sample_id_all) { @@ -580,6 +592,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_THROTTLE] = perf_event__throttle_swap, [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap, [PERF_RECORD_SAMPLE] = perf_event__all64_swap, + [PERF_RECORD_AUX] = perf_event__aux_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, @@ -1029,6 +1042,8 @@ static int machines__deliver_event(struct machines *machines, return tool->throttle(tool, event, sample, machine); case PERF_RECORD_UNTHROTTLE: return tool->unthrottle(tool, event, sample, machine); + case PERF_RECORD_AUX: + return tool->aux(tool, event, sample, machine); default: ++evlist->stats.nr_unknown_events; return -1; diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 20afe19a8eb0..8288caf0836e 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -43,6 +43,7 @@ struct perf_tool { fork, exit, lost, + aux, throttle, unthrottle; event_attr_op attr; -- 2.30.2