Skip to content

Commit 0a10247

Browse files
committed
perf: Set filters before mmaping events
We currently set the filters after we mmap the events, this is a race that let undesired events record themselves in the buffer before we had the time to set the filters. So set the filters before they can be recorded. That also librarizes the filters setting so that filtering can be done more easily from other tools than perf record later. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org>
1 parent 5807806 commit 0a10247

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

tools/perf/builtin-record.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,10 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
180180

181181
static void create_counter(struct perf_evsel *evsel, int cpu)
182182
{
183-
char *filter = evsel->filter;
184183
struct perf_event_attr *attr = &evsel->attr;
185184
struct perf_header_attr *h_attr;
186185
struct perf_sample_id *sid;
187186
int thread_index;
188-
int ret;
189187

190188
for (thread_index = 0; thread_index < evsel_list->threads->nr; thread_index++) {
191189
h_attr = get_header_attr(attr, evsel->idx);
@@ -204,16 +202,6 @@ static void create_counter(struct perf_evsel *evsel, int cpu)
204202
pr_warning("Not enough memory to add id\n");
205203
exit(-1);
206204
}
207-
208-
if (filter != NULL) {
209-
ret = ioctl(FD(evsel, cpu, thread_index),
210-
PERF_EVENT_IOC_SET_FILTER, filter);
211-
if (ret) {
212-
error("failed to set filter with %d (%s)\n", errno,
213-
strerror(errno));
214-
exit(-1);
215-
}
216-
}
217205
}
218206

219207
if (!sample_type)
@@ -367,6 +355,12 @@ static void open_counters(struct perf_evlist *evlist)
367355
}
368356
}
369357

358+
if (perf_evlist__set_filters(evlist)) {
359+
error("failed to set filter with %d (%s)\n", errno,
360+
strerror(errno));
361+
exit(-1);
362+
}
363+
370364
if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
371365
die("failed to mmap with %d (%s)\n", errno, strerror(errno));
372366

tools/perf/util/evlist.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,31 @@ void perf_evlist__delete_maps(struct perf_evlist *evlist)
348348
evlist->cpus = NULL;
349349
evlist->threads = NULL;
350350
}
351+
352+
int perf_evlist__set_filters(struct perf_evlist *evlist)
353+
{
354+
const struct thread_map *threads = evlist->threads;
355+
const struct cpu_map *cpus = evlist->cpus;
356+
struct perf_evsel *evsel;
357+
char *filter;
358+
int thread;
359+
int cpu;
360+
int err;
361+
int fd;
362+
363+
list_for_each_entry(evsel, &evlist->entries, node) {
364+
filter = evsel->filter;
365+
if (!filter)
366+
continue;
367+
for (cpu = 0; cpu < cpus->nr; cpu++) {
368+
for (thread = 0; thread < threads->nr; thread++) {
369+
fd = FD(evsel, cpu, thread);
370+
err = ioctl(fd, PERF_EVENT_IOC_SET_FILTER, filter);
371+
if (err)
372+
return err;
373+
}
374+
}
375+
}
376+
377+
return 0;
378+
}

tools/perf/util/evlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
6060
int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
6161
pid_t target_tid, const char *cpu_list);
6262
void perf_evlist__delete_maps(struct perf_evlist *evlist);
63+
int perf_evlist__set_filters(struct perf_evlist *evlist);
6364

6465
#endif /* __PERF_EVLIST_H */

0 commit comments

Comments
 (0)