Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
c093f308 40b746a0

+49 -7
+48 -5
tools/perf/arch/x86/util/intel-pt.c
··· 62 62 size_t snapshot_ref_buf_size; 63 63 int snapshot_ref_cnt; 64 64 struct intel_pt_snapshot_ref *snapshot_refs; 65 + size_t priv_size; 65 66 }; 66 67 67 68 static int intel_pt_parse_terms_with_default(struct list_head *formats, ··· 274 273 return attr; 275 274 } 276 275 277 - static size_t 278 - intel_pt_info_priv_size(struct auxtrace_record *itr __maybe_unused, 279 - struct perf_evlist *evlist __maybe_unused) 276 + static const char *intel_pt_find_filter(struct perf_evlist *evlist, 277 + struct perf_pmu *intel_pt_pmu) 280 278 { 281 - return INTEL_PT_AUXTRACE_PRIV_SIZE; 279 + struct perf_evsel *evsel; 280 + 281 + evlist__for_each_entry(evlist, evsel) { 282 + if (evsel->attr.type == intel_pt_pmu->type) 283 + return evsel->filter; 284 + } 285 + 286 + return NULL; 287 + } 288 + 289 + static size_t intel_pt_filter_bytes(const char *filter) 290 + { 291 + size_t len = filter ? strlen(filter) : 0; 292 + 293 + return len ? roundup(len + 1, 8) : 0; 294 + } 295 + 296 + static size_t 297 + intel_pt_info_priv_size(struct auxtrace_record *itr, struct perf_evlist *evlist) 298 + { 299 + struct intel_pt_recording *ptr = 300 + container_of(itr, struct intel_pt_recording, itr); 301 + const char *filter = intel_pt_find_filter(evlist, ptr->intel_pt_pmu); 302 + 303 + ptr->priv_size = (INTEL_PT_AUXTRACE_PRIV_MAX * sizeof(u64)) + 304 + intel_pt_filter_bytes(filter); 305 + 306 + return ptr->priv_size; 282 307 } 283 308 284 309 static void intel_pt_tsc_ctc_ratio(u32 *n, u32 *d) ··· 330 303 u64 tsc_bit, mtc_bit, mtc_freq_bits, cyc_bit, noretcomp_bit; 331 304 u32 tsc_ctc_ratio_n, tsc_ctc_ratio_d; 332 305 unsigned long max_non_turbo_ratio; 306 + size_t filter_str_len; 307 + const char *filter; 308 + u64 *info; 333 309 int err; 334 310 335 - if (priv_size != INTEL_PT_AUXTRACE_PRIV_SIZE) 311 + if (priv_size != ptr->priv_size) 336 312 return -EINVAL; 337 313 338 314 intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); ··· 351 321 if (perf_pmu__scan_file(intel_pt_pmu, "max_nonturbo_ratio", 352 322 "%lu", &max_non_turbo_ratio) != 1) 353 323 max_non_turbo_ratio = 0; 324 + 325 + filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu); 326 + filter_str_len = filter ? strlen(filter) : 0; 354 327 355 328 if (!session->evlist->nr_mmaps) 356 329 return -EINVAL; ··· 390 357 auxtrace_info->priv[INTEL_PT_TSC_CTC_D] = tsc_ctc_ratio_d; 391 358 auxtrace_info->priv[INTEL_PT_CYC_BIT] = cyc_bit; 392 359 auxtrace_info->priv[INTEL_PT_MAX_NONTURBO_RATIO] = max_non_turbo_ratio; 360 + auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] = filter_str_len; 361 + 362 + info = &auxtrace_info->priv[INTEL_PT_FILTER_STR_LEN] + 1; 363 + 364 + if (filter_str_len) { 365 + size_t len = intel_pt_filter_bytes(filter); 366 + 367 + strncpy((char *)info, filter, len); 368 + info += len >> 3; 369 + } 393 370 394 371 return 0; 395 372 }
+1 -2
tools/perf/util/intel-pt.h
··· 35 35 INTEL_PT_TSC_CTC_D, 36 36 INTEL_PT_CYC_BIT, 37 37 INTEL_PT_MAX_NONTURBO_RATIO, 38 + INTEL_PT_FILTER_STR_LEN, 38 39 INTEL_PT_AUXTRACE_PRIV_MAX, 39 40 }; 40 - 41 - #define INTEL_PT_AUXTRACE_PRIV_SIZE (INTEL_PT_AUXTRACE_PRIV_MAX * sizeof(u64)) 42 41 43 42 struct auxtrace_record; 44 43 struct perf_tool;