diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2016-09-23 10:38:45 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-09-29 10:17:05 -0400 |
| commit | c093f308cea3eb4be3ed6e7e9ad54bf67a26abe4 (patch) | |
| tree | dba16ec0bf49dd43d1621efbe9d9759ec14681ad /tools/perf/arch/x86/util | |
| parent | 40b746a06332799786ba557fe84184428bef62fb (diff) | |
perf intel-pt: Record address filter in AUXTRACE_INFO event
The address filter is needed to help decode the trace, so store it in
the AUXTRACE_INFO event.
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-14-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/arch/x86/util')
| -rw-r--r-- | tools/perf/arch/x86/util/intel-pt.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 18b21514c153..90fa2286edcf 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c | |||
| @@ -62,6 +62,7 @@ struct intel_pt_recording { | |||
| 62 | size_t snapshot_ref_buf_size; | 62 | size_t snapshot_ref_buf_size; |
| 63 | int snapshot_ref_cnt; | 63 | int snapshot_ref_cnt; |
| 64 | struct intel_pt_snapshot_ref *snapshot_refs; | 64 | struct intel_pt_snapshot_ref *snapshot_refs; |
| 65 | size_t priv_size; | ||
| 65 | }; | 66 | }; |
| 66 | 67 | ||
| 67 | static int intel_pt_parse_terms_with_default(struct list_head *formats, | 68 | static int intel_pt_parse_terms_with_default(struct list_head *formats, |
| @@ -273,11 +274,37 @@ intel_pt_pmu_default_config(struct perf_pmu *intel_pt_pmu) | |||
| 273 | return attr; | 274 | return attr; |
| 274 | } | 275 | } |
| 275 | 276 | ||
| 277 | static const char *intel_pt_find_filter(struct perf_evlist *evlist, | ||
| 278 | struct perf_pmu *intel_pt_pmu) | ||
| 279 | { | ||
| 280 | struct perf_evsel *evsel; | ||
| 281 | |||
| 282 | evlist__for_each_entry(evlist, evsel) { | ||
| 283 | if (evsel->attr.type == intel_pt_pmu->type) | ||
| 284 | return evsel->filter; | ||
| 285 | } | ||
| 286 | |||
| 287 | return NULL; | ||
| 288 | } | ||
| 289 | |||
| 290 | static size_t intel_pt_filter_bytes(const char *filter) | ||
| 291 | { | ||
| 292 | size_t len = filter ? strlen(filter) : 0; | ||
| 293 | |||
| 294 | return len ? roundup(len + 1, 8) : 0; | ||
| 295 | } | ||
| 296 | |||
| 276 | static size_t | 297 | static size_t |
| 277 | intel_pt_info_priv_size(struct auxtrace_record *itr __maybe_unused, | 298 | intel_pt_info_priv_size(struct auxtrace_record *itr, struct perf_evlist *evlist) |
| 278 | struct perf_evlist *evlist __maybe_unused) | ||
| 279 | { | 299 | { |
| 280 | return INTEL_PT_AUXTRACE_PRIV_SIZE; | 300 | struct intel_pt_recording *ptr = |
| 301 | container_of(itr, struct intel_pt_recording, itr); | ||
| 302 | const char *filter = intel_pt_find_filter(evlist, ptr->intel_pt_pmu); | ||
| 303 | |||
| 304 | ptr->priv_size = (INTEL_PT_AUXTRACE_PRIV_MAX * sizeof(u64)) + | ||
| 305 | intel_pt_filter_bytes(filter); | ||
| 306 | |||
| 307 | return ptr->priv_size; | ||
| 281 | } | 308 | } |
| 282 | 309 | ||
| 283 | static void intel_pt_tsc_ctc_ratio(u32 *n, u32 *d) | 310 | static void intel_pt_tsc_ctc_ratio(u32 *n, u32 *d) |
| @@ -303,9 +330,12 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, | |||
| 303 | u64 tsc_bit, mtc_bit, mtc_freq_bits, cyc_bit, noretcomp_bit; | 330 | u64 tsc_bit, mtc_bit, mtc_freq_bits, cyc_bit, noretcomp_bit; |
| 304 | u32 tsc_ctc_ratio_n, tsc_ctc_ratio_d; | 331 | u32 tsc_ctc_ratio_n, tsc_ctc_ratio_d; |
| 305 | unsigned long max_non_turbo_ratio; | 332 | unsigned long max_non_turbo_ratio; |
| 333 | size_t filter_str_len; | ||
| 334 | const char *filter; | ||
| 335 | u64 *info; | ||
| 306 | int err; | 336 | int err; |
| 307 | 337 | ||
| 308 | if (priv_size != INTEL_PT_AUXTRACE_PRIV_SIZE) | 338 | if (priv_size != ptr->priv_size) |
| 309 | return -EINVAL; | 339 | return -EINVAL; |
| 310 | 340 | ||
| 311 | intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); | 341 | intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); |
| @@ -322,6 +352,9 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, | |||
| 322 | "%lu", &max_non_turbo_ratio) != 1) | 352 | "%lu", &max_non_turbo_ratio) != 1) |
| 323 | max_non_turbo_ratio = 0; | 353 | max_non_turbo_ratio = 0; |
| 324 | 354 | ||
| 355 | filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu); | ||
| 356 | filter_str_len = filter ? strlen(filter) : 0; | ||
| 357 | |||
| 325 | if (!session->evlist->nr_mmaps) | 358 | if (!session->evlist->nr_mmaps) |
| 326 | return -EINVAL; | 359 | return -EINVAL; |
| 327 | 360 | ||
| @@ -357,6 +390,16 @@ static int intel_pt_info_fill(struct auxtrace_record *itr, | |||
| 357 | auxtrace_info->priv[INTEL_PT_TSC_CTC_D] = tsc_ctc_ratio_d; | 390 | auxtrace_info->priv[INTEL_PT_TSC_CTC_D] = tsc_ctc_ratio_d; |
| 358 | auxtrace_info->priv[INTEL_PT_CYC_BIT] = cyc_bit; | 391 | auxtrace_info->priv[INTEL_PT_CYC_BIT] = cyc_bit; |
| 359 | auxtrace_info->priv[INTEL_PT_MAX_NONTURBO_RATIO] = max_non_turbo_ratio; | 392 | auxtrace_info->priv[INTEL_PT_MAX_NONTURBO_RATIO] = max_non_turbo_ratio; |
| 393 | auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] = filter_str_len; | ||
| 394 | |||
| 395 | info = &auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] + 1; | ||
| 396 | |||
| 397 | if (filter_str_len) { | ||
| 398 | size_t len = intel_pt_filter_bytes(filter); | ||
| 399 | |||
| 400 | strncpy((char *)info, filter, len); | ||
| 401 | info += len >> 3; | ||
| 402 | } | ||
| 360 | 403 | ||
| 361 | return 0; | 404 | return 0; |
| 362 | } | 405 | } |
