4 #include "parse-events.h"
8 typedef void (*setup_probe_fn_t
)(struct perf_evsel
*evsel
);
10 static int perf_do_probe_api(setup_probe_fn_t fn
, int cpu
, const char *str
)
12 struct perf_evlist
*evlist
;
13 struct perf_evsel
*evsel
;
14 int err
= -EAGAIN
, fd
;
16 evlist
= perf_evlist__new();
20 if (parse_events(evlist
, str
))
23 evsel
= perf_evlist__first(evlist
);
25 fd
= sys_perf_event_open(&evsel
->attr
, -1, cpu
, -1, 0);
32 fd
= sys_perf_event_open(&evsel
->attr
, -1, cpu
, -1, 0);
42 perf_evlist__delete(evlist
);
46 static bool perf_probe_api(setup_probe_fn_t fn
)
48 const char *try[] = {"cycles:u", "instructions:u", "cpu-clock", NULL
};
52 cpus
= cpu_map__new(NULL
);
56 cpu_map__delete(cpus
);
59 ret
= perf_do_probe_api(fn
, cpu
, try[i
++]);
62 } while (ret
== -EAGAIN
&& try[i
]);
67 static void perf_probe_sample_identifier(struct perf_evsel
*evsel
)
69 evsel
->attr
.sample_type
|= PERF_SAMPLE_IDENTIFIER
;
72 bool perf_can_sample_identifier(void)
74 return perf_probe_api(perf_probe_sample_identifier
);
77 void perf_evlist__config(struct perf_evlist
*evlist
, struct record_opts
*opts
)
79 struct perf_evsel
*evsel
;
80 bool use_sample_identifier
= false;
83 * Set the evsel leader links before we configure attributes,
84 * since some might depend on this info.
87 perf_evlist__set_leader(evlist
);
89 if (evlist
->cpus
->map
[0] < 0)
90 opts
->no_inherit
= true;
92 evlist__for_each(evlist
, evsel
)
93 perf_evsel__config(evsel
, opts
);
95 if (evlist
->nr_entries
> 1) {
96 struct perf_evsel
*first
= perf_evlist__first(evlist
);
98 evlist__for_each(evlist
, evsel
) {
99 if (evsel
->attr
.sample_type
== first
->attr
.sample_type
)
101 use_sample_identifier
= perf_can_sample_identifier();
104 evlist__for_each(evlist
, evsel
)
105 perf_evsel__set_sample_id(evsel
, use_sample_identifier
);
108 perf_evlist__set_id_pos(evlist
);
111 static int get_max_rate(unsigned int *rate
)
114 const char *procfs
= procfs__mountpoint();
119 snprintf(path
, PATH_MAX
,
120 "%s/sys/kernel/perf_event_max_sample_rate", procfs
);
122 return filename__read_int(path
, (int *) rate
);
125 static int record_opts__config_freq(struct record_opts
*opts
)
127 bool user_freq
= opts
->user_freq
!= UINT_MAX
;
128 unsigned int max_rate
;
130 if (opts
->user_interval
!= ULLONG_MAX
)
131 opts
->default_interval
= opts
->user_interval
;
133 opts
->freq
= opts
->user_freq
;
136 * User specified count overrides default frequency.
138 if (opts
->default_interval
)
140 else if (opts
->freq
) {
141 opts
->default_interval
= opts
->freq
;
143 pr_err("frequency and count are zero, aborting\n");
147 if (get_max_rate(&max_rate
))
151 * User specified frequency is over current maximum.
153 if (user_freq
&& (max_rate
< opts
->freq
)) {
154 pr_err("Maximum frequency rate (%u) reached.\n"
155 "Please use -F freq option with lower value or consider\n"
156 "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
162 * Default frequency is over current maximum.
164 if (max_rate
< opts
->freq
) {
165 pr_warning("Lowering default frequency rate to %u.\n"
166 "Please consider tweaking "
167 "/proc/sys/kernel/perf_event_max_sample_rate.\n",
169 opts
->freq
= max_rate
;
175 int record_opts__config(struct record_opts
*opts
)
177 return record_opts__config_freq(opts
);
180 bool perf_evlist__can_select_event(struct perf_evlist
*evlist
, const char *str
)
182 struct perf_evlist
*temp_evlist
;
183 struct perf_evsel
*evsel
;
187 temp_evlist
= perf_evlist__new();
191 err
= parse_events(temp_evlist
, str
);
195 evsel
= perf_evlist__last(temp_evlist
);
197 if (!evlist
|| cpu_map__empty(evlist
->cpus
)) {
198 struct cpu_map
*cpus
= cpu_map__new(NULL
);
200 cpu
= cpus
? cpus
->map
[0] : 0;
201 cpu_map__delete(cpus
);
203 cpu
= evlist
->cpus
->map
[0];
206 fd
= sys_perf_event_open(&evsel
->attr
, -1, cpu
, -1, 0);
213 perf_evlist__delete(temp_evlist
);