aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/intel-pt.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2016-09-23 10:38:46 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-09-29 10:17:05 -0400
commit2b9e32c47fd3edb0373067de7a151775b0e005c2 (patch)
treed6389a93c248d5afbcb10f879995d96983201c20 /tools/perf/util/intel-pt.c
parentc093f308cea3eb4be3ed6e7e9ad54bf67a26abe4 (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.c51
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
108enum switch_state { 110enum 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
2029static void intel_pt_print_info(u64 *arr, int start, int finish) 2033static 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
2044static 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
2040static bool intel_pt_has(struct auxtrace_info_event *auxtrace_info, int pos) 2052static 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;
2220err_free: 2270err_free:
2271 zfree(&pt->filter);
2221 free(pt); 2272 free(pt);
2222 return err; 2273 return err;
2223} 2274}