diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2016-09-23 10:38:46 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-09-29 10:17:05 -0400 |
commit | 2b9e32c47fd3edb0373067de7a151775b0e005c2 (patch) | |
tree | d6389a93c248d5afbcb10f879995d96983201c20 /tools/perf/util/intel-pt.c | |
parent | c093f308cea3eb4be3ed6e7e9ad54bf67a26abe4 (diff) |
perf intel-pt: Read address filter from AUXTRACE_INFO event
Read the address filter from the AUXTRACE_INFO event in preparation for
using it to assist in decoding.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: http://lkml.kernel.org/r/1474641528-18776-15-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/intel-pt.c')
-rw-r--r-- | tools/perf/util/intel-pt.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index f16b00f55a19..c9fec19a7914 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -103,6 +103,8 @@ struct intel_pt { | |||
103 | unsigned max_non_turbo_ratio; | 103 | unsigned max_non_turbo_ratio; |
104 | 104 | ||
105 | unsigned long num_events; | 105 | unsigned long num_events; |
106 | |||
107 | char *filter; | ||
106 | }; | 108 | }; |
107 | 109 | ||
108 | enum switch_state { | 110 | enum switch_state { |
@@ -1774,6 +1776,7 @@ static void intel_pt_free(struct perf_session *session) | |||
1774 | intel_pt_free_events(session); | 1776 | intel_pt_free_events(session); |
1775 | session->auxtrace = NULL; | 1777 | session->auxtrace = NULL; |
1776 | thread__put(pt->unknown_thread); | 1778 | thread__put(pt->unknown_thread); |
1779 | zfree(&pt->filter); | ||
1777 | free(pt); | 1780 | free(pt); |
1778 | } | 1781 | } |
1779 | 1782 | ||
@@ -2024,6 +2027,7 @@ static const char * const intel_pt_info_fmts[] = { | |||
2024 | [INTEL_PT_TSC_CTC_D] = " TSC:CTC denominator %"PRIu64"\n", | 2027 | [INTEL_PT_TSC_CTC_D] = " TSC:CTC denominator %"PRIu64"\n", |
2025 | [INTEL_PT_CYC_BIT] = " CYC bit %#"PRIx64"\n", | 2028 | [INTEL_PT_CYC_BIT] = " CYC bit %#"PRIx64"\n", |
2026 | [INTEL_PT_MAX_NONTURBO_RATIO] = " Max non-turbo ratio %"PRIu64"\n", | 2029 | [INTEL_PT_MAX_NONTURBO_RATIO] = " Max non-turbo ratio %"PRIu64"\n", |
2030 | [INTEL_PT_FILTER_STR_LEN] = " Filter string len. %"PRIu64"\n", | ||
2027 | }; | 2031 | }; |
2028 | 2032 | ||
2029 | static void intel_pt_print_info(u64 *arr, int start, int finish) | 2033 | static void intel_pt_print_info(u64 *arr, int start, int finish) |
@@ -2037,6 +2041,14 @@ static void intel_pt_print_info(u64 *arr, int start, int finish) | |||
2037 | fprintf(stdout, intel_pt_info_fmts[i], arr[i]); | 2041 | fprintf(stdout, intel_pt_info_fmts[i], arr[i]); |
2038 | } | 2042 | } |
2039 | 2043 | ||
2044 | static void intel_pt_print_info_str(const char *name, const char *str) | ||
2045 | { | ||
2046 | if (!dump_trace) | ||
2047 | return; | ||
2048 | |||
2049 | fprintf(stdout, " %-20s%s\n", name, str ? str : ""); | ||
2050 | } | ||
2051 | |||
2040 | static bool intel_pt_has(struct auxtrace_info_event *auxtrace_info, int pos) | 2052 | static bool intel_pt_has(struct auxtrace_info_event *auxtrace_info, int pos) |
2041 | { | 2053 | { |
2042 | return auxtrace_info->header.size >= | 2054 | return auxtrace_info->header.size >= |
@@ -2049,6 +2061,8 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
2049 | struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; | 2061 | struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; |
2050 | size_t min_sz = sizeof(u64) * INTEL_PT_PER_CPU_MMAPS; | 2062 | size_t min_sz = sizeof(u64) * INTEL_PT_PER_CPU_MMAPS; |
2051 | struct intel_pt *pt; | 2063 | struct intel_pt *pt; |
2064 | void *info_end; | ||
2065 | u64 *info; | ||
2052 | int err; | 2066 | int err; |
2053 | 2067 | ||
2054 | if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + | 2068 | if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event) + |
@@ -2101,6 +2115,42 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
2101 | INTEL_PT_MAX_NONTURBO_RATIO); | 2115 | INTEL_PT_MAX_NONTURBO_RATIO); |
2102 | } | 2116 | } |
2103 | 2117 | ||
2118 | info = &auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] + 1; | ||
2119 | info_end = (void *)info + auxtrace_info->header.size; | ||
2120 | |||
2121 | if (intel_pt_has(auxtrace_info, INTEL_PT_FILTER_STR_LEN)) { | ||
2122 | size_t len; | ||
2123 | |||
2124 | len = auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN]; | ||
2125 | intel_pt_print_info(&auxtrace_info->priv[0], | ||
2126 | INTEL_PT_FILTER_STR_LEN, | ||
2127 | INTEL_PT_FILTER_STR_LEN); | ||
2128 | if (len) { | ||
2129 | const char *filter = (const char *)info; | ||
2130 | |||
2131 | len = roundup(len + 1, 8); | ||
2132 | info += len >> 3; | ||
2133 | if ((void *)info > info_end) { | ||
2134 | pr_err("%s: bad filter string length\n", __func__); | ||
2135 | err = -EINVAL; | ||
2136 | goto err_free_queues; | ||
2137 | } | ||
2138 | pt->filter = memdup(filter, len); | ||
2139 | if (!pt->filter) { | ||
2140 | err = -ENOMEM; | ||
2141 | goto err_free_queues; | ||
2142 | } | ||
2143 | if (session->header.needs_swap) | ||
2144 | mem_bswap_64(pt->filter, len); | ||
2145 | if (pt->filter[len - 1]) { | ||
2146 | pr_err("%s: filter string not null terminated\n", __func__); | ||
2147 | err = -EINVAL; | ||
2148 | goto err_free_queues; | ||
2149 | } | ||
2150 | } | ||
2151 | intel_pt_print_info_str("Filter string", pt->filter); | ||
2152 | } | ||
2153 | |||
2104 | pt->timeless_decoding = intel_pt_timeless_decoding(pt); | 2154 | pt->timeless_decoding = intel_pt_timeless_decoding(pt); |
2105 | pt->have_tsc = intel_pt_have_tsc(pt); | 2155 | pt->have_tsc = intel_pt_have_tsc(pt); |
2106 | pt->sampling_mode = false; | 2156 | pt->sampling_mode = false; |
@@ -2218,6 +2268,7 @@ err_free_queues: | |||
2218 | auxtrace_queues__free(&pt->queues); | 2268 | auxtrace_queues__free(&pt->queues); |
2219 | session->auxtrace = NULL; | 2269 | session->auxtrace = NULL; |
2220 | err_free: | 2270 | err_free: |
2271 | zfree(&pt->filter); | ||
2221 | free(pt); | 2272 | free(pt); |
2222 | return err; | 2273 | return err; |
2223 | } | 2274 | } |