hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/tools/perf/arch/x86/util/intel-pt.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * intel_pt.c: Intel Processor Trace support
34 * Copyright (c) 2013-2015, Intel Corporation.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
13
- *
145 */
156
167 #include <errno.h>
....@@ -19,21 +10,27 @@
1910 #include <linux/types.h>
2011 #include <linux/bitops.h>
2112 #include <linux/log2.h>
13
+#include <linux/zalloc.h>
2214 #include <cpuid.h>
2315
24
-#include "../../perf.h"
25
-#include "../../util/session.h"
26
-#include "../../util/event.h"
27
-#include "../../util/evlist.h"
28
-#include "../../util/evsel.h"
29
-#include "../../util/cpumap.h"
16
+#include "../../../util/session.h"
17
+#include "../../../util/event.h"
18
+#include "../../../util/evlist.h"
19
+#include "../../../util/evsel.h"
20
+#include "../../../util/evsel_config.h"
21
+#include "../../../util/cpumap.h"
22
+#include "../../../util/mmap.h"
3023 #include <subcmd/parse-options.h>
31
-#include "../../util/parse-events.h"
32
-#include "../../util/pmu.h"
33
-#include "../../util/debug.h"
34
-#include "../../util/auxtrace.h"
35
-#include "../../util/tsc.h"
36
-#include "../../util/intel-pt.h"
24
+#include "../../../util/parse-events.h"
25
+#include "../../../util/pmu.h"
26
+#include "../../../util/debug.h"
27
+#include "../../../util/auxtrace.h"
28
+#include "../../../util/perf_api_probe.h"
29
+#include "../../../util/record.h"
30
+#include "../../../util/target.h"
31
+#include "../../../util/tsc.h"
32
+#include <internal/lib.h> // page_size
33
+#include "../../../util/intel-pt.h"
3734
3835 #define KiB(x) ((x) * 1024)
3936 #define MiB(x) ((x) * 1024 * 1024)
....@@ -52,7 +49,7 @@
5249 struct auxtrace_record itr;
5350 struct perf_pmu *intel_pt_pmu;
5451 int have_sched_switch;
55
- struct perf_evlist *evlist;
52
+ struct evlist *evlist;
5653 bool snapshot_mode;
5754 bool snapshot_init_done;
5855 size_t snapshot_size;
....@@ -62,7 +59,8 @@
6259 size_t priv_size;
6360 };
6461
65
-static int intel_pt_parse_terms_with_default(struct list_head *formats,
62
+static int intel_pt_parse_terms_with_default(const char *pmu_name,
63
+ struct list_head *formats,
6664 const char *str,
6765 u64 *config)
6866 {
....@@ -81,7 +79,8 @@
8179 goto out_free;
8280
8381 attr.config = *config;
84
- err = perf_pmu__config_terms(formats, &attr, terms, true, NULL);
82
+ err = perf_pmu__config_terms(pmu_name, formats, &attr, terms, true,
83
+ NULL);
8584 if (err)
8685 goto out_free;
8786
....@@ -91,11 +90,12 @@
9190 return err;
9291 }
9392
94
-static int intel_pt_parse_terms(struct list_head *formats, const char *str,
95
- u64 *config)
93
+static int intel_pt_parse_terms(const char *pmu_name, struct list_head *formats,
94
+ const char *str, u64 *config)
9695 {
9796 *config = 0;
98
- return intel_pt_parse_terms_with_default(formats, str, config);
97
+ return intel_pt_parse_terms_with_default(pmu_name, formats, str,
98
+ config);
9999 }
100100
101101 static u64 intel_pt_masked_bits(u64 mask, u64 bits)
....@@ -118,9 +118,9 @@
118118 }
119119
120120 static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str,
121
- struct perf_evlist *evlist, u64 *res)
121
+ struct evlist *evlist, u64 *res)
122122 {
123
- struct perf_evsel *evsel;
123
+ struct evsel *evsel;
124124 u64 mask;
125125
126126 *res = 0;
....@@ -130,8 +130,8 @@
130130 return -EINVAL;
131131
132132 evlist__for_each_entry(evlist, evsel) {
133
- if (evsel->attr.type == intel_pt_pmu->type) {
134
- *res = intel_pt_masked_bits(mask, evsel->attr.config);
133
+ if (evsel->core.attr.type == intel_pt_pmu->type) {
134
+ *res = intel_pt_masked_bits(mask, evsel->core.attr.config);
135135 return 0;
136136 }
137137 }
....@@ -140,7 +140,7 @@
140140 }
141141
142142 static size_t intel_pt_psb_period(struct perf_pmu *intel_pt_pmu,
143
- struct perf_evlist *evlist)
143
+ struct evlist *evlist)
144144 {
145145 u64 val;
146146 int err, topa_multiple_entries;
....@@ -232,7 +232,8 @@
232232
233233 pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf);
234234
235
- intel_pt_parse_terms(&intel_pt_pmu->format, buf, &config);
235
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, buf,
236
+ &config);
236237
237238 return config;
238239 }
....@@ -276,13 +277,13 @@
276277 return attr;
277278 }
278279
279
-static const char *intel_pt_find_filter(struct perf_evlist *evlist,
280
+static const char *intel_pt_find_filter(struct evlist *evlist,
280281 struct perf_pmu *intel_pt_pmu)
281282 {
282
- struct perf_evsel *evsel;
283
+ struct evsel *evsel;
283284
284285 evlist__for_each_entry(evlist, evsel) {
285
- if (evsel->attr.type == intel_pt_pmu->type)
286
+ if (evsel->core.attr.type == intel_pt_pmu->type)
286287 return evsel->filter;
287288 }
288289
....@@ -297,7 +298,7 @@
297298 }
298299
299300 static size_t
300
-intel_pt_info_priv_size(struct auxtrace_record *itr, struct perf_evlist *evlist)
301
+intel_pt_info_priv_size(struct auxtrace_record *itr, struct evlist *evlist)
301302 {
302303 struct intel_pt_recording *ptr =
303304 container_of(itr, struct intel_pt_recording, itr);
....@@ -320,7 +321,7 @@
320321
321322 static int intel_pt_info_fill(struct auxtrace_record *itr,
322323 struct perf_session *session,
323
- struct auxtrace_info_event *auxtrace_info,
324
+ struct perf_record_auxtrace_info *auxtrace_info,
324325 size_t priv_size)
325326 {
326327 struct intel_pt_recording *ptr =
....@@ -334,19 +335,22 @@
334335 unsigned long max_non_turbo_ratio;
335336 size_t filter_str_len;
336337 const char *filter;
337
- u64 *info;
338
+ __u64 *info;
338339 int err;
339340
340341 if (priv_size != ptr->priv_size)
341342 return -EINVAL;
342343
343
- intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit);
344
- intel_pt_parse_terms(&intel_pt_pmu->format, "noretcomp",
345
- &noretcomp_bit);
346
- intel_pt_parse_terms(&intel_pt_pmu->format, "mtc", &mtc_bit);
344
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
345
+ "tsc", &tsc_bit);
346
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
347
+ "noretcomp", &noretcomp_bit);
348
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
349
+ "mtc", &mtc_bit);
347350 mtc_freq_bits = perf_pmu__format_bits(&intel_pt_pmu->format,
348351 "mtc_period");
349
- intel_pt_parse_terms(&intel_pt_pmu->format, "cyc", &cyc_bit);
352
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
353
+ "cyc", &cyc_bit);
350354
351355 intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d);
352356
....@@ -357,10 +361,10 @@
357361 filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu);
358362 filter_str_len = filter ? strlen(filter) : 0;
359363
360
- if (!session->evlist->nr_mmaps)
364
+ if (!session->evlist->core.nr_mmaps)
361365 return -EINVAL;
362366
363
- pc = session->evlist->mmap[0].base;
367
+ pc = session->evlist->mmap[0].core.base;
364368 if (pc) {
365369 err = perf_read_tsc_conversion(pc, &tc);
366370 if (err) {
....@@ -373,7 +377,7 @@
373377 ui__warning("Intel Processor Trace: TSC not available\n");
374378 }
375379
376
- per_cpu_mmaps = !cpu_map__empty(session->evlist->cpus);
380
+ per_cpu_mmaps = !perf_cpu_map__empty(session->evlist->core.cpus);
377381
378382 auxtrace_info->type = PERF_AUXTRACE_INTEL_PT;
379383 auxtrace_info->priv[INTEL_PT_PMU_TYPE] = intel_pt_pmu->type;
....@@ -406,10 +410,10 @@
406410 return 0;
407411 }
408412
409
-static int intel_pt_track_switches(struct perf_evlist *evlist)
413
+static int intel_pt_track_switches(struct evlist *evlist)
410414 {
411415 const char *sched_switch = "sched:sched_switch";
412
- struct perf_evsel *evsel;
416
+ struct evsel *evsel;
413417 int err;
414418
415419 if (!perf_evlist__can_select_event(evlist, sched_switch))
....@@ -422,12 +426,12 @@
422426 return err;
423427 }
424428
425
- evsel = perf_evlist__last(evlist);
429
+ evsel = evlist__last(evlist);
426430
427
- perf_evsel__set_sample_bit(evsel, CPU);
428
- perf_evsel__set_sample_bit(evsel, TIME);
431
+ evsel__set_sample_bit(evsel, CPU);
432
+ evsel__set_sample_bit(evsel, TIME);
429433
430
- evsel->system_wide = true;
434
+ evsel->core.system_wide = true;
431435 evsel->no_aux_samples = true;
432436 evsel->immediate = true;
433437
....@@ -521,7 +525,7 @@
521525 }
522526
523527 static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu,
524
- struct perf_evsel *evsel)
528
+ struct evsel *evsel)
525529 {
526530 int err;
527531 char c;
....@@ -534,39 +538,95 @@
534538 * sets pt=0, which avoids senseless kernel errors.
535539 */
536540 if (perf_pmu__scan_file(intel_pt_pmu, "format/pt", "%c", &c) == 1 &&
537
- !(evsel->attr.config & 1)) {
541
+ !(evsel->core.attr.config & 1)) {
538542 pr_warning("pt=0 doesn't make sense, forcing pt=1\n");
539
- evsel->attr.config |= 1;
543
+ evsel->core.attr.config |= 1;
540544 }
541545
542546 err = intel_pt_val_config_term(intel_pt_pmu, "caps/cycle_thresholds",
543547 "cyc_thresh", "caps/psb_cyc",
544
- evsel->attr.config);
548
+ evsel->core.attr.config);
545549 if (err)
546550 return err;
547551
548552 err = intel_pt_val_config_term(intel_pt_pmu, "caps/mtc_periods",
549553 "mtc_period", "caps/mtc",
550
- evsel->attr.config);
554
+ evsel->core.attr.config);
551555 if (err)
552556 return err;
553557
554558 return intel_pt_val_config_term(intel_pt_pmu, "caps/psb_periods",
555559 "psb_period", "caps/psb_cyc",
556
- evsel->attr.config);
560
+ evsel->core.attr.config);
561
+}
562
+
563
+static void intel_pt_config_sample_mode(struct perf_pmu *intel_pt_pmu,
564
+ struct evsel *evsel)
565
+{
566
+ u64 user_bits = 0, bits;
567
+ struct evsel_config_term *term = evsel__get_config_term(evsel, CFG_CHG);
568
+
569
+ if (term)
570
+ user_bits = term->val.cfg_chg;
571
+
572
+ bits = perf_pmu__format_bits(&intel_pt_pmu->format, "psb_period");
573
+
574
+ /* Did user change psb_period */
575
+ if (bits & user_bits)
576
+ return;
577
+
578
+ /* Set psb_period to 0 */
579
+ evsel->core.attr.config &= ~bits;
580
+}
581
+
582
+static void intel_pt_min_max_sample_sz(struct evlist *evlist,
583
+ size_t *min_sz, size_t *max_sz)
584
+{
585
+ struct evsel *evsel;
586
+
587
+ evlist__for_each_entry(evlist, evsel) {
588
+ size_t sz = evsel->core.attr.aux_sample_size;
589
+
590
+ if (!sz)
591
+ continue;
592
+ if (min_sz && (sz < *min_sz || !*min_sz))
593
+ *min_sz = sz;
594
+ if (max_sz && sz > *max_sz)
595
+ *max_sz = sz;
596
+ }
597
+}
598
+
599
+/*
600
+ * Currently, there is not enough information to disambiguate different PEBS
601
+ * events, so only allow one.
602
+ */
603
+static bool intel_pt_too_many_aux_output(struct evlist *evlist)
604
+{
605
+ struct evsel *evsel;
606
+ int aux_output_cnt = 0;
607
+
608
+ evlist__for_each_entry(evlist, evsel)
609
+ aux_output_cnt += !!evsel->core.attr.aux_output;
610
+
611
+ if (aux_output_cnt > 1) {
612
+ pr_err(INTEL_PT_PMU_NAME " supports at most one event with aux-output\n");
613
+ return true;
614
+ }
615
+
616
+ return false;
557617 }
558618
559619 static int intel_pt_recording_options(struct auxtrace_record *itr,
560
- struct perf_evlist *evlist,
620
+ struct evlist *evlist,
561621 struct record_opts *opts)
562622 {
563623 struct intel_pt_recording *ptr =
564624 container_of(itr, struct intel_pt_recording, itr);
565625 struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu;
566626 bool have_timing_info, need_immediate = false;
567
- struct perf_evsel *evsel, *intel_pt_evsel = NULL;
568
- const struct cpu_map *cpus = evlist->cpus;
569
- bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
627
+ struct evsel *evsel, *intel_pt_evsel = NULL;
628
+ const struct perf_cpu_map *cpus = evlist->core.cpus;
629
+ bool privileged = perf_event_paranoid_check(-1);
570630 u64 tsc_bit;
571631 int err;
572632
....@@ -574,13 +634,14 @@
574634 ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
575635
576636 evlist__for_each_entry(evlist, evsel) {
577
- if (evsel->attr.type == intel_pt_pmu->type) {
637
+ if (evsel->core.attr.type == intel_pt_pmu->type) {
578638 if (intel_pt_evsel) {
579639 pr_err("There may be only one " INTEL_PT_PMU_NAME " event\n");
580640 return -EINVAL;
581641 }
582
- evsel->attr.freq = 0;
583
- evsel->attr.sample_period = 1;
642
+ evsel->core.attr.freq = 0;
643
+ evsel->core.attr.sample_period = 1;
644
+ evsel->no_aux_samples = true;
584645 intel_pt_evsel = evsel;
585646 opts->full_auxtrace = true;
586647 }
....@@ -591,13 +652,24 @@
591652 return -EINVAL;
592653 }
593654
655
+ if (opts->auxtrace_snapshot_mode && opts->auxtrace_sample_mode) {
656
+ pr_err("Snapshot mode (" INTEL_PT_PMU_NAME " PMU) and sample trace cannot be used together\n");
657
+ return -EINVAL;
658
+ }
659
+
594660 if (opts->use_clockid) {
595661 pr_err("Cannot use clockid (-k option) with " INTEL_PT_PMU_NAME "\n");
596662 return -EINVAL;
597663 }
598664
665
+ if (intel_pt_too_many_aux_output(evlist))
666
+ return -EINVAL;
667
+
599668 if (!opts->full_auxtrace)
600669 return 0;
670
+
671
+ if (opts->auxtrace_sample_mode)
672
+ intel_pt_config_sample_mode(intel_pt_pmu, intel_pt_evsel);
601673
602674 err = intel_pt_validate_config(intel_pt_pmu, intel_pt_evsel);
603675 if (err)
....@@ -648,6 +720,34 @@
648720 opts->auxtrace_snapshot_size, psb_period);
649721 }
650722
723
+ /* Set default sizes for sample mode */
724
+ if (opts->auxtrace_sample_mode) {
725
+ size_t psb_period = intel_pt_psb_period(intel_pt_pmu, evlist);
726
+ size_t min_sz = 0, max_sz = 0;
727
+
728
+ intel_pt_min_max_sample_sz(evlist, &min_sz, &max_sz);
729
+ if (!opts->auxtrace_mmap_pages && !privileged &&
730
+ opts->mmap_pages == UINT_MAX)
731
+ opts->mmap_pages = KiB(256) / page_size;
732
+ if (!opts->auxtrace_mmap_pages) {
733
+ size_t sz = round_up(max_sz, page_size) / page_size;
734
+
735
+ opts->auxtrace_mmap_pages = roundup_pow_of_two(sz);
736
+ }
737
+ if (max_sz > opts->auxtrace_mmap_pages * (size_t)page_size) {
738
+ pr_err("Sample size %zu must not be greater than AUX area tracing mmap size %zu\n",
739
+ max_sz,
740
+ opts->auxtrace_mmap_pages * (size_t)page_size);
741
+ return -EINVAL;
742
+ }
743
+ pr_debug2("Intel PT min. sample size: %zu max. sample size: %zu\n",
744
+ min_sz, max_sz);
745
+ if (psb_period &&
746
+ min_sz <= psb_period + INTEL_PT_PSB_PERIOD_NEAR)
747
+ ui__warning("Intel PT sample size (%zu) may be too small for PSB period (%zu)\n",
748
+ min_sz, psb_period);
749
+ }
750
+
651751 /* Set default sizes for full trace mode */
652752 if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
653753 if (privileged) {
....@@ -664,7 +764,7 @@
664764 size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
665765 size_t min_sz;
666766
667
- if (opts->auxtrace_snapshot_mode)
767
+ if (opts->auxtrace_snapshot_mode || opts->auxtrace_sample_mode)
668768 min_sz = KiB(4);
669769 else
670770 min_sz = KiB(8);
....@@ -676,9 +776,10 @@
676776 }
677777 }
678778
679
- intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit);
779
+ intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format,
780
+ "tsc", &tsc_bit);
680781
681
- if (opts->full_auxtrace && (intel_pt_evsel->attr.config & tsc_bit))
782
+ if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit))
682783 have_timing_info = true;
683784 else
684785 have_timing_info = false;
....@@ -687,32 +788,33 @@
687788 * Per-cpu recording needs sched_switch events to distinguish different
688789 * threads.
689790 */
690
- if (have_timing_info && !cpu_map__empty(cpus)) {
791
+ if (have_timing_info && !perf_cpu_map__empty(cpus) &&
792
+ !record_opts__no_switch_events(opts)) {
691793 if (perf_can_record_switch_events()) {
692794 bool cpu_wide = !target__none(&opts->target) &&
693795 !target__has_task(&opts->target);
694796
695797 if (!cpu_wide && perf_can_record_cpu_wide()) {
696
- struct perf_evsel *switch_evsel;
798
+ struct evsel *switch_evsel;
697799
698800 err = parse_events(evlist, "dummy:u", NULL);
699801 if (err)
700802 return err;
701803
702
- switch_evsel = perf_evlist__last(evlist);
804
+ switch_evsel = evlist__last(evlist);
703805
704
- switch_evsel->attr.freq = 0;
705
- switch_evsel->attr.sample_period = 1;
706
- switch_evsel->attr.context_switch = 1;
806
+ switch_evsel->core.attr.freq = 0;
807
+ switch_evsel->core.attr.sample_period = 1;
808
+ switch_evsel->core.attr.context_switch = 1;
707809
708
- switch_evsel->system_wide = true;
810
+ switch_evsel->core.system_wide = true;
709811 switch_evsel->no_aux_samples = true;
710812 switch_evsel->immediate = true;
711813
712
- perf_evsel__set_sample_bit(switch_evsel, TID);
713
- perf_evsel__set_sample_bit(switch_evsel, TIME);
714
- perf_evsel__set_sample_bit(switch_evsel, CPU);
715
- perf_evsel__reset_sample_bit(switch_evsel, BRANCH_STACK);
814
+ evsel__set_sample_bit(switch_evsel, TID);
815
+ evsel__set_sample_bit(switch_evsel, TIME);
816
+ evsel__set_sample_bit(switch_evsel, CPU);
817
+ evsel__reset_sample_bit(switch_evsel, BRANCH_STACK);
716818
717819 opts->record_switch_events = false;
718820 ptr->have_sched_switch = 3;
....@@ -735,6 +837,10 @@
735837 }
736838 }
737839
840
+ if (have_timing_info && !intel_pt_evsel->core.attr.exclude_kernel &&
841
+ perf_can_record_text_poke_events() && perf_can_record_cpu_wide())
842
+ opts->text_poke = true;
843
+
738844 if (intel_pt_evsel) {
739845 /*
740846 * To obtain the auxtrace buffer file descriptor, the auxtrace
....@@ -745,44 +851,45 @@
745851 * In the case of per-cpu mmaps, we need the CPU on the
746852 * AUX event.
747853 */
748
- if (!cpu_map__empty(cpus))
749
- perf_evsel__set_sample_bit(intel_pt_evsel, CPU);
854
+ if (!perf_cpu_map__empty(cpus))
855
+ evsel__set_sample_bit(intel_pt_evsel, CPU);
750856 }
751857
752858 /* Add dummy event to keep tracking */
753859 if (opts->full_auxtrace) {
754
- struct perf_evsel *tracking_evsel;
860
+ struct evsel *tracking_evsel;
755861
756862 err = parse_events(evlist, "dummy:u", NULL);
757863 if (err)
758864 return err;
759865
760
- tracking_evsel = perf_evlist__last(evlist);
866
+ tracking_evsel = evlist__last(evlist);
761867
762868 perf_evlist__set_tracking_event(evlist, tracking_evsel);
763869
764
- tracking_evsel->attr.freq = 0;
765
- tracking_evsel->attr.sample_period = 1;
870
+ tracking_evsel->core.attr.freq = 0;
871
+ tracking_evsel->core.attr.sample_period = 1;
766872
767873 tracking_evsel->no_aux_samples = true;
768874 if (need_immediate)
769875 tracking_evsel->immediate = true;
770876
771877 /* In per-cpu case, always need the time of mmap events etc */
772
- if (!cpu_map__empty(cpus)) {
773
- perf_evsel__set_sample_bit(tracking_evsel, TIME);
878
+ if (!perf_cpu_map__empty(cpus)) {
879
+ evsel__set_sample_bit(tracking_evsel, TIME);
774880 /* And the CPU for switch events */
775
- perf_evsel__set_sample_bit(tracking_evsel, CPU);
881
+ evsel__set_sample_bit(tracking_evsel, CPU);
776882 }
777
- perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
883
+ evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
778884 }
779885
780886 /*
781887 * Warn the user when we do not have enough information to decode i.e.
782888 * per-cpu with no sched_switch (except workload-only).
783889 */
784
- if (!ptr->have_sched_switch && !cpu_map__empty(cpus) &&
785
- !target__none(&opts->target))
890
+ if (!ptr->have_sched_switch && !perf_cpu_map__empty(cpus) &&
891
+ !target__none(&opts->target) &&
892
+ !intel_pt_evsel->core.attr.exclude_user)
786893 ui__warning("Intel Processor Trace decoding will not be possible except for kernel tracing!\n");
787894
788895 return 0;
....@@ -792,11 +899,11 @@
792899 {
793900 struct intel_pt_recording *ptr =
794901 container_of(itr, struct intel_pt_recording, itr);
795
- struct perf_evsel *evsel;
902
+ struct evsel *evsel;
796903
797904 evlist__for_each_entry(ptr->evlist, evsel) {
798
- if (evsel->attr.type == ptr->intel_pt_pmu->type)
799
- return perf_evsel__disable(evsel);
905
+ if (evsel->core.attr.type == ptr->intel_pt_pmu->type)
906
+ return evsel__disable(evsel);
800907 }
801908 return -EINVAL;
802909 }
....@@ -805,11 +912,11 @@
805912 {
806913 struct intel_pt_recording *ptr =
807914 container_of(itr, struct intel_pt_recording, itr);
808
- struct perf_evsel *evsel;
915
+ struct evsel *evsel;
809916
810917 evlist__for_each_entry(ptr->evlist, evsel) {
811
- if (evsel->attr.type == ptr->intel_pt_pmu->type)
812
- return perf_evsel__enable(evsel);
918
+ if (evsel->core.attr.type == ptr->intel_pt_pmu->type)
919
+ return evsel__enable(evsel);
813920 }
814921 return -EINVAL;
815922 }
....@@ -1074,20 +1181,6 @@
10741181 return rdtsc();
10751182 }
10761183
1077
-static int intel_pt_read_finish(struct auxtrace_record *itr, int idx)
1078
-{
1079
- struct intel_pt_recording *ptr =
1080
- container_of(itr, struct intel_pt_recording, itr);
1081
- struct perf_evsel *evsel;
1082
-
1083
- evlist__for_each_entry(ptr->evlist, evsel) {
1084
- if (evsel->attr.type == ptr->intel_pt_pmu->type)
1085
- return perf_evlist__enable_event_idx(ptr->evlist, evsel,
1086
- idx);
1087
- }
1088
- return -EINVAL;
1089
-}
1090
-
10911184 struct auxtrace_record *intel_pt_recording_init(int *err)
10921185 {
10931186 struct perf_pmu *intel_pt_pmu = perf_pmu__find(INTEL_PT_PMU_NAME);
....@@ -1108,6 +1201,7 @@
11081201 }
11091202
11101203 ptr->intel_pt_pmu = intel_pt_pmu;
1204
+ ptr->itr.pmu = intel_pt_pmu;
11111205 ptr->itr.recording_options = intel_pt_recording_options;
11121206 ptr->itr.info_priv_size = intel_pt_info_priv_size;
11131207 ptr->itr.info_fill = intel_pt_info_fill;
....@@ -1117,6 +1211,11 @@
11171211 ptr->itr.find_snapshot = intel_pt_find_snapshot;
11181212 ptr->itr.parse_snapshot_options = intel_pt_parse_snapshot_options;
11191213 ptr->itr.reference = intel_pt_reference;
1120
- ptr->itr.read_finish = intel_pt_read_finish;
1214
+ ptr->itr.read_finish = auxtrace_record__read_finish;
1215
+ /*
1216
+ * Decoding starts at a PSB packet. Minimum PSB period is 2K so 4K
1217
+ * should give at least 1 PSB per sample.
1218
+ */
1219
+ ptr->itr.default_aux_sample_size = 4096;
11211220 return &ptr->itr;
11221221 }