diff options
author | Yang Jihong <yangjihong1@huawei.com> | 2023-10-13 09:59:45 +0200 |
---|---|---|
committer | Namhyung Kim <namhyung@kernel.org> | 2023-10-20 08:38:27 +0200 |
commit | c4a852635eddcf4130a93e687bc7b120b19fd1b7 (patch) | |
tree | e8a8dbbd5cd44b6ceddf40480b56016585a8cf38 /tools | |
parent | perf vendor events: Update PMC used in PM_RUN_INST_CMPL event for power10 pla... (diff) | |
download | linux-c4a852635eddcf4130a93e687bc7b120b19fd1b7.tar.xz linux-c4a852635eddcf4130a93e687bc7b120b19fd1b7.zip |
perf data: Increase RLIMIT_NOFILE limit when open too many files in perf_data__create_dir()
If using parallel threads to collect data, perf record needs at least 6 fds
per CPU. (one for sys_perf_event_open, four for pipe msg and ack of the
pipe, see record__thread_data_open_pipes(), and one for open perf.data.XXX)
For an environment with more than 100 cores, if perf record uses both
`-a` and `--threads` options, it is easy to exceed the upper limit of the
file descriptor number, when we run out of them try to increase the limits.
Before:
$ ulimit -n
1024
$ lscpu | grep 'On-line CPU(s)'
On-line CPU(s) list: 0-159
$ perf record --threads -a sleep 1
Failed to create data directory: Too many open files
After:
$ ulimit -n
1024
$ lscpu | grep 'On-line CPU(s)'
On-line CPU(s) list: 0-159
$ perf record --threads -a sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.394 MB perf.data (1576 samples) ]
Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20231013075945.698874-1-yangjihong1@huawei.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/data.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index fc16299c915f..098f9e3bb2e7 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -17,6 +17,7 @@ #include "util.h" // rm_rf_perf_data() #include "debug.h" #include "header.h" +#include "evsel.h" #include <internal/lib.h> static void close_dir(struct perf_data_file *files, int nr) @@ -35,6 +36,7 @@ void perf_data__close_dir(struct perf_data *data) int perf_data__create_dir(struct perf_data *data, int nr) { + enum rlimit_action set_rlimit = NO_CHANGE; struct perf_data_file *files = NULL; int i, ret; @@ -54,11 +56,21 @@ int perf_data__create_dir(struct perf_data *data, int nr) goto out_err; } +retry_open: ret = open(file->path, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); if (ret < 0) { + /* + * If using parallel threads to collect data, + * perf record needs at least 6 fds per CPU. + * When we run out of them try to increase the limits. + */ + if (errno == EMFILE && evsel__increase_rlimit(&set_rlimit)) + goto retry_open; + ret = -errno; goto out_err; } + set_rlimit = NO_CHANGE; file->fd = ret; } |