Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf evlist: Don't poll and mmap overwritable events

There's no need to receive events from overwritable ring buffer.
Instead, perf should make them run in background until some external
event of interest takes place. This patch makes ignores normal events from
overwrite evlists.

Overwritable events must be mapped readonly and backward, so if evlist
and evsel doesn't match (evsel->overwrite is true but either evlist is
read/write or evlist is not backward, and vice versa), skip mapping it.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1464056944-166978-3-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
[ Split from a larger patch ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Wang Nan and committed by
Arnaldo Carvalho de Melo
f3058a1c c45628b0

+19 -4
+19 -4
tools/perf/util/evlist.c
··· 462 462 return 0; 463 463 } 464 464 465 - static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx) 465 + static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx, short revent) 466 466 { 467 - int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); 467 + int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP); 468 468 /* 469 469 * Save the idx so that when we filter out fds POLLHUP'ed we can 470 470 * close the associated evlist->mmap[] entry. ··· 480 480 481 481 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) 482 482 { 483 - return __perf_evlist__add_pollfd(evlist, fd, -1); 483 + return __perf_evlist__add_pollfd(evlist, fd, -1, POLLIN); 484 484 } 485 485 486 486 static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd) ··· 983 983 return 0; 984 984 } 985 985 986 + static bool 987 + perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, 988 + struct perf_evsel *evsel) 989 + { 990 + if (evsel->overwrite) 991 + return false; 992 + return true; 993 + } 994 + 986 995 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, 987 996 struct mmap_params *mp, int cpu, 988 997 int thread, int *output) 989 998 { 990 999 struct perf_evsel *evsel; 1000 + int revent; 991 1001 992 1002 evlist__for_each(evlist, evsel) { 993 1003 int fd; 1004 + 1005 + if (evsel->overwrite != (evlist->overwrite && evlist->backward)) 1006 + continue; 994 1007 995 1008 if (evsel->system_wide && thread) 996 1009 continue; ··· 1021 1008 perf_evlist__mmap_get(evlist, idx); 1022 1009 } 1023 1010 1011 + revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0; 1012 + 1024 1013 /* 1025 1014 * The system_wide flag causes a selected event to be opened 1026 1015 * always without a pid. Consequently it will never get a ··· 1031 1016 * Therefore don't add it for polling. 1032 1017 */ 1033 1018 if (!evsel->system_wide && 1034 - __perf_evlist__add_pollfd(evlist, fd, idx) < 0) { 1019 + __perf_evlist__add_pollfd(evlist, fd, idx, revent) < 0) { 1035 1020 perf_evlist__mmap_put(evlist, idx); 1036 1021 return -1; 1037 1022 }