diff options
Diffstat (limited to 'tools/perf/util/record.c')
-rw-r--r-- | tools/perf/util/record.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index fe8079edbdc1..cf69325b985f 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -14,6 +14,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) | |||
14 | struct perf_evsel *evsel; | 14 | struct perf_evsel *evsel; |
15 | unsigned long flags = perf_event_open_cloexec_flag(); | 15 | unsigned long flags = perf_event_open_cloexec_flag(); |
16 | int err = -EAGAIN, fd; | 16 | int err = -EAGAIN, fd; |
17 | static pid_t pid = -1; | ||
17 | 18 | ||
18 | evlist = perf_evlist__new(); | 19 | evlist = perf_evlist__new(); |
19 | if (!evlist) | 20 | if (!evlist) |
@@ -24,14 +25,22 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) | |||
24 | 25 | ||
25 | evsel = perf_evlist__first(evlist); | 26 | evsel = perf_evlist__first(evlist); |
26 | 27 | ||
27 | fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); | 28 | while (1) { |
28 | if (fd < 0) | 29 | fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); |
29 | goto out_delete; | 30 | if (fd < 0) { |
31 | if (pid == -1 && errno == EACCES) { | ||
32 | pid = 0; | ||
33 | continue; | ||
34 | } | ||
35 | goto out_delete; | ||
36 | } | ||
37 | break; | ||
38 | } | ||
30 | close(fd); | 39 | close(fd); |
31 | 40 | ||
32 | fn(evsel); | 41 | fn(evsel); |
33 | 42 | ||
34 | fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); | 43 | fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); |
35 | if (fd < 0) { | 44 | if (fd < 0) { |
36 | if (errno == EINVAL) | 45 | if (errno == EINVAL) |
37 | err = -EINVAL; | 46 | err = -EINVAL; |
@@ -47,7 +56,7 @@ out_delete: | |||
47 | 56 | ||
48 | static bool perf_probe_api(setup_probe_fn_t fn) | 57 | static bool perf_probe_api(setup_probe_fn_t fn) |
49 | { | 58 | { |
50 | const char *try[] = {"cycles:u", "instructions:u", "cpu-clock", NULL}; | 59 | const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL}; |
51 | struct cpu_map *cpus; | 60 | struct cpu_map *cpus; |
52 | int cpu, ret, i = 0; | 61 | int cpu, ret, i = 0; |
53 | 62 | ||
@@ -106,7 +115,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) | |||
106 | 115 | ||
107 | evlist__for_each(evlist, evsel) { | 116 | evlist__for_each(evlist, evsel) { |
108 | perf_evsel__config(evsel, opts); | 117 | perf_evsel__config(evsel, opts); |
109 | if (!evsel->idx && use_comm_exec) | 118 | if (evsel->tracking && use_comm_exec) |
110 | evsel->attr.comm_exec = 1; | 119 | evsel->attr.comm_exec = 1; |
111 | } | 120 | } |
112 | 121 | ||
@@ -201,6 +210,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) | |||
201 | struct perf_evsel *evsel; | 210 | struct perf_evsel *evsel; |
202 | int err, fd, cpu; | 211 | int err, fd, cpu; |
203 | bool ret = false; | 212 | bool ret = false; |
213 | pid_t pid = -1; | ||
204 | 214 | ||
205 | temp_evlist = perf_evlist__new(); | 215 | temp_evlist = perf_evlist__new(); |
206 | if (!temp_evlist) | 216 | if (!temp_evlist) |
@@ -221,12 +231,20 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) | |||
221 | cpu = evlist->cpus->map[0]; | 231 | cpu = evlist->cpus->map[0]; |
222 | } | 232 | } |
223 | 233 | ||
224 | fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, | 234 | while (1) { |
225 | perf_event_open_cloexec_flag()); | 235 | fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, |
226 | if (fd >= 0) { | 236 | perf_event_open_cloexec_flag()); |
227 | close(fd); | 237 | if (fd < 0) { |
228 | ret = true; | 238 | if (pid == -1 && errno == EACCES) { |
239 | pid = 0; | ||
240 | continue; | ||
241 | } | ||
242 | goto out_delete; | ||
243 | } | ||
244 | break; | ||
229 | } | 245 | } |
246 | close(fd); | ||
247 | ret = true; | ||
230 | 248 | ||
231 | out_delete: | 249 | out_delete: |
232 | perf_evlist__delete(temp_evlist); | 250 | perf_evlist__delete(temp_evlist); |