summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2019-03-14 18:49:55 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-19 10:56:20 -0400
commit03724b2e9c45d931eff0f304f2d3363ade65ca89 (patch)
treea5036771e339008135c20a5cbbcd9b38744f5726 /tools
parent6f40b2a5dac4b448fe1e8d94dc4238cd95cd5e34 (diff)
perf record: Allow to limit number of reported perf.data files
When doing long term recording and waiting for some event to snapshot on, we often only care about the last minute or so. The --switch-output command line option supports rotating the perf.data file when the size exceeds a threshold. But the disk would still be filled with unnecessary old files. Add a new option to only keep a number of rotated files, so that the disk space usage can be limited. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> LPU-Reference: 20190314225002.30108-3-andi@firstfloor.org Link: https://lkml.kernel.org/n/tip-y5u2lik0ragt4vlktz6qc9ks@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt4
-rw-r--r--tools/perf/builtin-record.c30
-rw-r--r--tools/perf/util/data.c11
-rw-r--r--tools/perf/util/data.h2
4 files changed, 39 insertions, 8 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 8f0c2be34848..8fe4dffcadd0 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -495,6 +495,10 @@ overhead. You can still switch them on with:
495 495
496 --switch-output --no-no-buildid --no-no-buildid-cache 496 --switch-output --no-no-buildid --no-no-buildid-cache
497 497
498--switch-max-files=N::
499
500When rotating perf.data with --switch-output, only keep N files.
501
498--dry-run:: 502--dry-run::
499Parse options then exit. --dry-run can be used to detect errors in cmdline 503Parse options then exit. --dry-run can be used to detect errors in cmdline
500options. 504options.
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a468d882e74f..02d7c40b2d10 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -62,6 +62,9 @@ struct switch_output {
62 unsigned long time; 62 unsigned long time;
63 const char *str; 63 const char *str;
64 bool set; 64 bool set;
65 char **filenames;
66 int num_files;
67 int cur_file;
65}; 68};
66 69
67struct record { 70struct record {
@@ -892,6 +895,7 @@ record__switch_output(struct record *rec, bool at_exit)
892{ 895{
893 struct perf_data *data = &rec->data; 896 struct perf_data *data = &rec->data;
894 int fd, err; 897 int fd, err;
898 char *new_filename;
895 899
896 /* Same Size: "2015122520103046"*/ 900 /* Same Size: "2015122520103046"*/
897 char timestamp[] = "InvalidTimestamp"; 901 char timestamp[] = "InvalidTimestamp";
@@ -912,7 +916,7 @@ record__switch_output(struct record *rec, bool at_exit)
912 916
913 fd = perf_data__switch(data, timestamp, 917 fd = perf_data__switch(data, timestamp,
914 rec->session->header.data_offset, 918 rec->session->header.data_offset,
915 at_exit); 919 at_exit, &new_filename);
916 if (fd >= 0 && !at_exit) { 920 if (fd >= 0 && !at_exit) {
917 rec->bytes_written = 0; 921 rec->bytes_written = 0;
918 rec->session->header.data_size = 0; 922 rec->session->header.data_size = 0;
@@ -922,6 +926,21 @@ record__switch_output(struct record *rec, bool at_exit)
922 fprintf(stderr, "[ perf record: Dump %s.%s ]\n", 926 fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
923 data->path, timestamp); 927 data->path, timestamp);
924 928
929 if (rec->switch_output.num_files) {
930 int n = rec->switch_output.cur_file + 1;
931
932 if (n >= rec->switch_output.num_files)
933 n = 0;
934 rec->switch_output.cur_file = n;
935 if (rec->switch_output.filenames[n]) {
936 remove(rec->switch_output.filenames[n]);
937 free(rec->switch_output.filenames[n]);
938 }
939 rec->switch_output.filenames[n] = new_filename;
940 } else {
941 free(new_filename);
942 }
943
925 /* Output tracking events */ 944 /* Output tracking events */
926 if (!at_exit) { 945 if (!at_exit) {
927 record__synthesize(rec, false); 946 record__synthesize(rec, false);
@@ -1973,6 +1992,8 @@ static struct option __record_options[] = {
1973 &record.switch_output.set, "signal,size,time", 1992 &record.switch_output.set, "signal,size,time",
1974 "Switch output when receive SIGUSR2 or cross size,time threshold", 1993 "Switch output when receive SIGUSR2 or cross size,time threshold",
1975 "signal"), 1994 "signal"),
1995 OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
1996 "Limit number of switch output generated files"),
1976 OPT_BOOLEAN(0, "dry-run", &dry_run, 1997 OPT_BOOLEAN(0, "dry-run", &dry_run,
1977 "Parse options then exit"), 1998 "Parse options then exit"),
1978#ifdef HAVE_AIO_SUPPORT 1999#ifdef HAVE_AIO_SUPPORT
@@ -2059,6 +2080,13 @@ int cmd_record(int argc, const char **argv)
2059 alarm(rec->switch_output.time); 2080 alarm(rec->switch_output.time);
2060 } 2081 }
2061 2082
2083 if (rec->switch_output.num_files) {
2084 rec->switch_output.filenames = calloc(sizeof(char *),
2085 rec->switch_output.num_files);
2086 if (!rec->switch_output.filenames)
2087 return -EINVAL;
2088 }
2089
2062 /* 2090 /*
2063 * Allow aliases to facilitate the lookup of symbols for address 2091 * Allow aliases to facilitate the lookup of symbols for address
2064 * filters. Refer to auxtrace_parse_filters(). 2092 * filters. Refer to auxtrace_parse_filters().
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index c6b67efea11a..6a64f713710d 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -361,9 +361,9 @@ ssize_t perf_data__write(struct perf_data *data,
361 361
362int perf_data__switch(struct perf_data *data, 362int perf_data__switch(struct perf_data *data,
363 const char *postfix, 363 const char *postfix,
364 size_t pos, bool at_exit) 364 size_t pos, bool at_exit,
365 char **new_filepath)
365{ 366{
366 char *new_filepath;
367 int ret; 367 int ret;
368 368
369 if (check_pipe(data)) 369 if (check_pipe(data))
@@ -371,15 +371,15 @@ int perf_data__switch(struct perf_data *data,
371 if (perf_data__is_read(data)) 371 if (perf_data__is_read(data))
372 return -EINVAL; 372 return -EINVAL;
373 373
374 if (asprintf(&new_filepath, "%s.%s", data->path, postfix) < 0) 374 if (asprintf(new_filepath, "%s.%s", data->path, postfix) < 0)
375 return -ENOMEM; 375 return -ENOMEM;
376 376
377 /* 377 /*
378 * Only fire a warning, don't return error, continue fill 378 * Only fire a warning, don't return error, continue fill
379 * original file. 379 * original file.
380 */ 380 */
381 if (rename(data->path, new_filepath)) 381 if (rename(data->path, *new_filepath))
382 pr_warning("Failed to rename %s to %s\n", data->path, new_filepath); 382 pr_warning("Failed to rename %s to %s\n", data->path, *new_filepath);
383 383
384 if (!at_exit) { 384 if (!at_exit) {
385 close(data->file.fd); 385 close(data->file.fd);
@@ -396,7 +396,6 @@ int perf_data__switch(struct perf_data *data,
396 } 396 }
397 ret = data->file.fd; 397 ret = data->file.fd;
398out: 398out:
399 free(new_filepath);
400 return ret; 399 return ret;
401} 400}
402 401
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h
index 6aef8746469f..259868a39019 100644
--- a/tools/perf/util/data.h
+++ b/tools/perf/util/data.h
@@ -70,7 +70,7 @@ ssize_t perf_data_file__write(struct perf_data_file *file,
70 */ 70 */
71int perf_data__switch(struct perf_data *data, 71int perf_data__switch(struct perf_data *data,
72 const char *postfix, 72 const char *postfix,
73 size_t pos, bool at_exit); 73 size_t pos, bool at_exit, char **new_filepath);
74 74
75int perf_data__create_dir(struct perf_data *data, int nr); 75int perf_data__create_dir(struct perf_data *data, int nr);
76int perf_data__open_dir(struct perf_data *data); 76int perf_data__open_dir(struct perf_data *data);