Messages in this thread Patch in this message |  | | From | Alexander Shishkin <> | Subject | [PATCH v0 46/71] perf session: Add Instruction Tracing hooks | Date | Wed, 11 Dec 2013 14:36:58 +0200 |
| |
From: Adrian Hunter <adrian.hunter@intel.com>
Hook into session processing so that Instruction Trace decoding can synthesize events transparently to the tools.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/util/itrace.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/session.c | 45 +++++++++++++++++++++++++++++++++++++------ tools/perf/util/session.h | 3 +++ 3 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/itrace.h b/tools/perf/util/itrace.h index da52a29..e6b0cc0 100644 --- a/tools/perf/util/itrace.h +++ b/tools/perf/util/itrace.h @@ -26,6 +26,7 @@ #include <linux/perf_event.h> #include "../perf.h" +#include "session.h" #include "types.h" union perf_event; @@ -35,6 +36,18 @@ struct perf_tool; struct perf_record_opts; struct itrace_info_event; +struct itrace { + int (*process_event)(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool); + int (*flush_events)(struct perf_session *session, + struct perf_tool *tool); + void (*free_events)(struct perf_session *session); + void (*free)(struct perf_session *session); + unsigned long long error_count; +}; + /** * struct itrace_mmap - records an mmap at PERF_EVENT_ITRACE_OFFSET. * @base: address of mapped area @@ -164,4 +177,40 @@ int perf_event__synthesize_itrace(struct perf_tool *tool, size_t size, u64 offset, u64 ref, int idx, u32 tid, u32 cpu); +static inline int itrace__process_event(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool) +{ + if (!session->itrace) + return 0; + + return session->itrace->process_event(session, event, sample, tool); +} + +static inline int itrace__flush_events(struct perf_session *session, + struct perf_tool *tool) +{ + if (!session->itrace) + return 0; + + return session->itrace->flush_events(session, tool); +} + +static inline void itrace__free_events(struct perf_session *session) +{ + if (!session->itrace) + return; + + return session->itrace->free_events(session); +} + +static inline void itrace__free(struct perf_session *session) +{ + if (!session->itrace) + return; + + return session->itrace->free(session); +} + #endif diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 95067b6..55aead5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -15,6 +15,7 @@ #include "cpumap.h" #include "perf_regs.h" #include "vdso.h" +#include "itrace.h" static int perf_session__open(struct perf_session *session) { @@ -148,6 +149,7 @@ static void perf_session_env__delete(struct perf_session_env *env) void perf_session__delete(struct perf_session *session) { + itrace__free(session); perf_session__destroy_kernel_maps(session); perf_session__delete_dead_threads(session); perf_session__delete_threads(session); @@ -1022,11 +1024,11 @@ perf_session__deliver_sample(struct perf_session *session, &sample->read.one, machine); } -static int perf_session_deliver_event(struct perf_session *session, - union perf_event *event, - struct perf_sample *sample, - struct perf_tool *tool, - u64 file_offset) +static int __perf_session__deliver_event(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool, + u64 file_offset) { struct perf_evsel *evsel; struct machine *machine; @@ -1095,6 +1097,24 @@ static int perf_session_deliver_event(struct perf_session *session, } } +static int perf_session_deliver_event(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool, + u64 file_offset) +{ + int ret; + + ret = itrace__process_event(session, event, sample, tool); + if (ret < 0) + return ret; + if (ret > 0) + return 0; + + return __perf_session__deliver_event(session, event, sample, tool, + file_offset); +} + static s64 perf_session__process_user_event(struct perf_session *session, union perf_event *event, struct perf_tool *tool, @@ -1146,7 +1166,7 @@ int perf_session__deliver_synth_event(struct perf_session *session, return perf_session__process_user_event(session, event, tool, 0); - return perf_session_deliver_event(session, event, sample, tool, 0); + return __perf_session__deliver_event(session, event, sample, tool, 0); } static void event_swap(union perf_event *event, bool sample_id_all) @@ -1258,6 +1278,11 @@ static void perf_session__warn_about_errors(const struct perf_session *session, "Do you have a KVM guest running and not using 'perf kvm'?\n", session->stats.nr_unprocessable_samples); } + + if (session->itrace && session->itrace->error_count) { + ui__warning("%llu instruction trace errors\n", + session->itrace->error_count); + } } volatile int session_done; @@ -1346,10 +1371,14 @@ done: /* do the final flush for ordered samples */ session->ordered_samples.next_flush = ULLONG_MAX; err = flush_sample_queue(session, tool); + if (err) + goto out_err; + err = itrace__flush_events(session, tool); out_err: free(buf); perf_session__warn_about_errors(session, tool); perf_session_free_sample_buffers(session); + itrace__free_events(session); return err; } @@ -1492,10 +1521,14 @@ out: /* do the final flush for ordered samples */ session->ordered_samples.next_flush = ULLONG_MAX; err = flush_sample_queue(session, tool); + if (err) + goto out_err; + err = itrace__flush_events(session, tool); out_err: ui_progress__finish(); perf_session__warn_about_errors(session, tool); perf_session_free_sample_buffers(session); + itrace__free_events(session); session->one_mmap = false; return err; } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 64d8145..9000193 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -29,10 +29,13 @@ struct ordered_samples { unsigned int nr_samples; }; +struct itrace; + struct perf_session { struct perf_header header; struct machines machines; struct perf_evlist *evlist; + struct itrace *itrace; struct trace_event tevent; struct events_stats stats; bool repipe; -- 1.8.5.1
|  |