Commit | Line | Data |
---|---|---|
a3f22d50 | 1 | #include <stdbool.h> |
e0fcfb08 | 2 | #include <stdlib.h> |
a3f22d50 PH |
3 | #include <linux/kernel.h> |
4 | #include <linux/types.h> | |
5 | #include <linux/bitops.h> | |
6 | #include <linux/log2.h> | |
7f7c536f | 7 | #include <linux/zalloc.h> |
a3f22d50 PH |
8 | |
9 | #include "../../util/evlist.h" | |
10 | #include "../../util/auxtrace.h" | |
11 | #include "../../util/evsel.h" | |
aeb00b1a | 12 | #include "../../util/record.h" |
a3f22d50 PH |
13 | |
14 | #define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */ | |
15 | #define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */ | |
16 | #define DEFAULT_AUX_PAGES 128 | |
17 | #define DEFAULT_FREQ 4000 | |
18 | ||
19 | static void cpumsf_free(struct auxtrace_record *itr) | |
20 | { | |
21 | free(itr); | |
22 | } | |
23 | ||
24 | static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused, | |
63503dba | 25 | struct evlist *evlist __maybe_unused) |
a3f22d50 PH |
26 | { |
27 | return 0; | |
28 | } | |
29 | ||
30 | static int | |
31 | cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused, | |
32 | struct perf_session *session __maybe_unused, | |
72932371 | 33 | struct perf_record_auxtrace_info *auxtrace_info __maybe_unused, |
a3f22d50 PH |
34 | size_t priv_size __maybe_unused) |
35 | { | |
b96e6615 | 36 | auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF; |
a3f22d50 PH |
37 | return 0; |
38 | } | |
39 | ||
40 | static unsigned long | |
41 | cpumsf_reference(struct auxtrace_record *itr __maybe_unused) | |
42 | { | |
43 | return 0; | |
44 | } | |
45 | ||
46 | static int | |
47 | cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused, | |
63503dba | 48 | struct evlist *evlist __maybe_unused, |
a3f22d50 PH |
49 | struct record_opts *opts) |
50 | { | |
51 | unsigned int factor = 1; | |
52 | unsigned int pages; | |
53 | ||
54 | opts->full_auxtrace = true; | |
55 | ||
56 | /* | |
57 | * The AUX buffer size should be set properly to avoid | |
58 | * overflow of samples if it is not set explicitly. | |
59 | * DEFAULT_AUX_PAGES is an proper size when sampling frequency | |
60 | * is DEFAULT_FREQ. It is expected to hold about 1/2 second | |
61 | * of sampling data. The size used for AUX buffer will scale | |
62 | * according to the specified frequency and DEFAULT_FREQ. | |
63 | */ | |
64 | if (!opts->auxtrace_mmap_pages) { | |
65 | if (opts->user_freq != UINT_MAX) | |
66 | factor = (opts->user_freq + DEFAULT_FREQ | |
67 | - 1) / DEFAULT_FREQ; | |
68 | pages = DEFAULT_AUX_PAGES * factor; | |
69 | opts->auxtrace_mmap_pages = roundup_pow_of_two(pages); | |
70 | } | |
71 | ||
72 | return 0; | |
73 | } | |
74 | ||
75 | static int | |
76 | cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused, | |
77 | struct record_opts *opts __maybe_unused, | |
78 | const char *str __maybe_unused) | |
79 | { | |
80 | return 0; | |
81 | } | |
82 | ||
83 | /* | |
84 | * auxtrace_record__init is called when perf record | |
85 | * check if the event really need auxtrace | |
86 | */ | |
63503dba | 87 | struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, |
a3f22d50 PH |
88 | int *err) |
89 | { | |
90 | struct auxtrace_record *aux; | |
32dcd021 | 91 | struct evsel *pos; |
a3f22d50 PH |
92 | int diagnose = 0; |
93 | ||
5d9946c3 | 94 | *err = 0; |
6484d2f9 | 95 | if (evlist->core.nr_entries == 0) |
a3f22d50 PH |
96 | return NULL; |
97 | ||
98 | evlist__for_each_entry(evlist, pos) { | |
1fc632ce | 99 | if (pos->core.attr.config == PERF_EVENT_CPUM_SF_DIAG) { |
a3f22d50 | 100 | diagnose = 1; |
7df319e5 | 101 | pos->needs_auxtrace_mmap = true; |
a3f22d50 PH |
102 | break; |
103 | } | |
104 | } | |
105 | ||
106 | if (!diagnose) | |
107 | return NULL; | |
108 | ||
109 | /* sampling in diagnose mode. alloc aux buffer */ | |
110 | aux = zalloc(sizeof(*aux)); | |
111 | if (aux == NULL) { | |
112 | *err = -ENOMEM; | |
113 | return NULL; | |
114 | } | |
115 | ||
116 | aux->parse_snapshot_options = cpumsf_parse_snapshot_options; | |
117 | aux->recording_options = cpumsf_recording_options; | |
118 | aux->info_priv_size = cpumsf_info_priv_size; | |
119 | aux->info_fill = cpumsf_info_fill; | |
120 | aux->free = cpumsf_free; | |
121 | aux->reference = cpumsf_reference; | |
122 | ||
123 | return aux; | |
124 | } |