diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Documentation/perf-record.txt | 4 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 76 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 16 | ||||
-rw-r--r-- | tools/perf/util/trace-event-parse.c | 2 |
4 files changed, 56 insertions, 42 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index fc46c0b40f6e..020d871c7934 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -58,7 +58,7 @@ OPTIONS | |||
58 | 58 | ||
59 | -f:: | 59 | -f:: |
60 | --force:: | 60 | --force:: |
61 | Overwrite existing data file. | 61 | Overwrite existing data file. (deprecated) |
62 | 62 | ||
63 | -c:: | 63 | -c:: |
64 | --count=:: | 64 | --count=:: |
@@ -101,7 +101,7 @@ OPTIONS | |||
101 | 101 | ||
102 | -R:: | 102 | -R:: |
103 | --raw-samples:: | 103 | --raw-samples:: |
104 | Collect raw sample records from all opened counters (typically for tracepoint counters). | 104 | Collect raw sample records from all opened counters (default for tracepoint counters). |
105 | 105 | ||
106 | SEE ALSO | 106 | SEE ALSO |
107 | -------- | 107 | -------- |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0bde31bc8e2e..a1b99eeac3c0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -26,13 +26,20 @@ | |||
26 | #include <unistd.h> | 26 | #include <unistd.h> |
27 | #include <sched.h> | 27 | #include <sched.h> |
28 | 28 | ||
29 | enum write_mode_t { | ||
30 | WRITE_FORCE, | ||
31 | WRITE_APPEND | ||
32 | }; | ||
33 | |||
29 | static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; | 34 | static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; |
30 | 35 | ||
36 | static unsigned int user_interval = UINT_MAX; | ||
31 | static long default_interval = 0; | 37 | static long default_interval = 0; |
32 | 38 | ||
33 | static int nr_cpus = 0; | 39 | static int nr_cpus = 0; |
34 | static unsigned int page_size; | 40 | static unsigned int page_size; |
35 | static unsigned int mmap_pages = 128; | 41 | static unsigned int mmap_pages = 128; |
42 | static unsigned int user_freq = UINT_MAX; | ||
36 | static int freq = 1000; | 43 | static int freq = 1000; |
37 | static int output; | 44 | static int output; |
38 | static int pipe_output = 0; | 45 | static int pipe_output = 0; |
@@ -48,8 +55,7 @@ static pid_t *all_tids = NULL; | |||
48 | static int thread_num = 0; | 55 | static int thread_num = 0; |
49 | static pid_t child_pid = -1; | 56 | static pid_t child_pid = -1; |
50 | static bool inherit = true; | 57 | static bool inherit = true; |
51 | static bool force = false; | 58 | static enum write_mode_t write_mode = WRITE_FORCE; |
52 | static bool append_file = false; | ||
53 | static bool call_graph = false; | 59 | static bool call_graph = false; |
54 | static bool inherit_stat = false; | 60 | static bool inherit_stat = false; |
55 | static bool no_samples = false; | 61 | static bool no_samples = false; |
@@ -257,10 +263,19 @@ static void create_counter(int counter, int cpu) | |||
257 | if (nr_counters > 1) | 263 | if (nr_counters > 1) |
258 | attr->sample_type |= PERF_SAMPLE_ID; | 264 | attr->sample_type |= PERF_SAMPLE_ID; |
259 | 265 | ||
260 | if (freq) { | 266 | /* |
261 | attr->sample_type |= PERF_SAMPLE_PERIOD; | 267 | * We default some events to a 1 default interval. But keep |
262 | attr->freq = 1; | 268 | * it a weak assumption overridable by the user. |
263 | attr->sample_freq = freq; | 269 | */ |
270 | if (!attr->sample_period || (user_freq != UINT_MAX && | ||
271 | user_interval != UINT_MAX)) { | ||
272 | if (freq) { | ||
273 | attr->sample_type |= PERF_SAMPLE_PERIOD; | ||
274 | attr->freq = 1; | ||
275 | attr->sample_freq = freq; | ||
276 | } else { | ||
277 | attr->sample_period = default_interval; | ||
278 | } | ||
264 | } | 279 | } |
265 | 280 | ||
266 | if (no_samples) | 281 | if (no_samples) |
@@ -467,26 +482,19 @@ static int __cmd_record(int argc, const char **argv) | |||
467 | if (!strcmp(output_name, "-")) | 482 | if (!strcmp(output_name, "-")) |
468 | pipe_output = 1; | 483 | pipe_output = 1; |
469 | else if (!stat(output_name, &st) && st.st_size) { | 484 | else if (!stat(output_name, &st) && st.st_size) { |
470 | if (!force) { | 485 | if (write_mode == WRITE_FORCE) { |
471 | if (!append_file) { | ||
472 | pr_err("Error, output file %s exists, use -A " | ||
473 | "to append or -f to overwrite.\n", | ||
474 | output_name); | ||
475 | exit(-1); | ||
476 | } | ||
477 | } else { | ||
478 | char oldname[PATH_MAX]; | 486 | char oldname[PATH_MAX]; |
479 | snprintf(oldname, sizeof(oldname), "%s.old", | 487 | snprintf(oldname, sizeof(oldname), "%s.old", |
480 | output_name); | 488 | output_name); |
481 | unlink(oldname); | 489 | unlink(oldname); |
482 | rename(output_name, oldname); | 490 | rename(output_name, oldname); |
483 | } | 491 | } |
484 | } else { | 492 | } else if (write_mode == WRITE_APPEND) { |
485 | append_file = false; | 493 | write_mode = WRITE_FORCE; |
486 | } | 494 | } |
487 | 495 | ||
488 | flags = O_CREAT|O_RDWR; | 496 | flags = O_CREAT|O_RDWR; |
489 | if (append_file) | 497 | if (write_mode == WRITE_APPEND) |
490 | file_new = 0; | 498 | file_new = 0; |
491 | else | 499 | else |
492 | flags |= O_TRUNC; | 500 | flags |= O_TRUNC; |
@@ -500,7 +508,8 @@ static int __cmd_record(int argc, const char **argv) | |||
500 | exit(-1); | 508 | exit(-1); |
501 | } | 509 | } |
502 | 510 | ||
503 | session = perf_session__new(output_name, O_WRONLY, force); | 511 | session = perf_session__new(output_name, O_WRONLY, |
512 | write_mode == WRITE_FORCE); | ||
504 | if (session == NULL) { | 513 | if (session == NULL) { |
505 | pr_err("Not enough memory for reading perf file header\n"); | 514 | pr_err("Not enough memory for reading perf file header\n"); |
506 | return -1; | 515 | return -1; |
@@ -721,6 +730,8 @@ static const char * const record_usage[] = { | |||
721 | NULL | 730 | NULL |
722 | }; | 731 | }; |
723 | 732 | ||
733 | static bool force, append_file; | ||
734 | |||
724 | static const struct option options[] = { | 735 | static const struct option options[] = { |
725 | OPT_CALLBACK('e', "event", NULL, "event", | 736 | OPT_CALLBACK('e', "event", NULL, "event", |
726 | "event selector. use 'perf list' to list available events", | 737 | "event selector. use 'perf list' to list available events", |
@@ -742,14 +753,14 @@ static const struct option options[] = { | |||
742 | OPT_INTEGER('C', "profile_cpu", &profile_cpu, | 753 | OPT_INTEGER('C', "profile_cpu", &profile_cpu, |
743 | "CPU to profile on"), | 754 | "CPU to profile on"), |
744 | OPT_BOOLEAN('f', "force", &force, | 755 | OPT_BOOLEAN('f', "force", &force, |
745 | "overwrite existing data file"), | 756 | "overwrite existing data file (deprecated)"), |
746 | OPT_LONG('c', "count", &default_interval, | 757 | OPT_LONG('c', "count", &user_interval, |
747 | "event period to sample"), | 758 | "event period to sample"), |
748 | OPT_STRING('o', "output", &output_name, "file", | 759 | OPT_STRING('o', "output", &output_name, "file", |
749 | "output file name"), | 760 | "output file name"), |
750 | OPT_BOOLEAN('i', "inherit", &inherit, | 761 | OPT_BOOLEAN('i', "inherit", &inherit, |
751 | "child tasks inherit counters"), | 762 | "child tasks inherit counters"), |
752 | OPT_INTEGER('F', "freq", &freq, | 763 | OPT_INTEGER('F', "freq", &user_freq, |
753 | "profile at this frequency"), | 764 | "profile at this frequency"), |
754 | OPT_INTEGER('m', "mmap-pages", &mmap_pages, | 765 | OPT_INTEGER('m', "mmap-pages", &mmap_pages, |
755 | "number of mmap data pages"), | 766 | "number of mmap data pages"), |
@@ -770,7 +781,6 @@ static const struct option options[] = { | |||
770 | 781 | ||
771 | int cmd_record(int argc, const char **argv, const char *prefix __used) | 782 | int cmd_record(int argc, const char **argv, const char *prefix __used) |
772 | { | 783 | { |
773 | int counter; | ||
774 | int i,j; | 784 | int i,j; |
775 | 785 | ||
776 | argc = parse_options(argc, argv, options, record_usage, | 786 | argc = parse_options(argc, argv, options, record_usage, |
@@ -779,6 +789,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
779 | !system_wide && profile_cpu == -1) | 789 | !system_wide && profile_cpu == -1) |
780 | usage_with_options(record_usage, options); | 790 | usage_with_options(record_usage, options); |
781 | 791 | ||
792 | if (force && append_file) { | ||
793 | fprintf(stderr, "Can't overwrite and append at the same time." | ||
794 | " You need to choose between -f and -A"); | ||
795 | usage_with_options(record_usage, options); | ||
796 | } else if (append_file) { | ||
797 | write_mode = WRITE_APPEND; | ||
798 | } else { | ||
799 | write_mode = WRITE_FORCE; | ||
800 | } | ||
801 | |||
782 | symbol__init(); | 802 | symbol__init(); |
783 | 803 | ||
784 | if (!nr_counters) { | 804 | if (!nr_counters) { |
@@ -818,6 +838,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
818 | if (!event_array) | 838 | if (!event_array) |
819 | return -ENOMEM; | 839 | return -ENOMEM; |
820 | 840 | ||
841 | if (user_interval != UINT_MAX) | ||
842 | default_interval = user_interval; | ||
843 | if (user_freq != UINT_MAX) | ||
844 | freq = user_freq; | ||
845 | |||
821 | /* | 846 | /* |
822 | * User specified count overrides default frequency. | 847 | * User specified count overrides default frequency. |
823 | */ | 848 | */ |
@@ -830,12 +855,5 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
830 | exit(EXIT_FAILURE); | 855 | exit(EXIT_FAILURE); |
831 | } | 856 | } |
832 | 857 | ||
833 | for (counter = 0; counter < nr_counters; counter++) { | ||
834 | if (attrs[counter].sample_period) | ||
835 | continue; | ||
836 | |||
837 | attrs[counter].sample_period = default_interval; | ||
838 | } | ||
839 | |||
840 | return __cmd_record(argc, argv); | 858 | return __cmd_record(argc, argv); |
841 | } | 859 | } |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 435781e0c205..3b4ec6797565 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -410,7 +410,6 @@ static enum event_result | |||
410 | parse_single_tracepoint_event(char *sys_name, | 410 | parse_single_tracepoint_event(char *sys_name, |
411 | const char *evt_name, | 411 | const char *evt_name, |
412 | unsigned int evt_length, | 412 | unsigned int evt_length, |
413 | char *flags, | ||
414 | struct perf_event_attr *attr, | 413 | struct perf_event_attr *attr, |
415 | const char **strp) | 414 | const char **strp) |
416 | { | 415 | { |
@@ -419,13 +418,11 @@ parse_single_tracepoint_event(char *sys_name, | |||
419 | u64 id; | 418 | u64 id; |
420 | int fd; | 419 | int fd; |
421 | 420 | ||
422 | if (flags) { | 421 | attr->sample_type |= PERF_SAMPLE_RAW; |
423 | if (!strncmp(flags, "record", strlen(flags))) { | 422 | attr->sample_type |= PERF_SAMPLE_TIME; |
424 | attr->sample_type |= PERF_SAMPLE_RAW; | 423 | attr->sample_type |= PERF_SAMPLE_CPU; |
425 | attr->sample_type |= PERF_SAMPLE_TIME; | 424 | |
426 | attr->sample_type |= PERF_SAMPLE_CPU; | 425 | attr->sample_period = 1; |
427 | } | ||
428 | } | ||
429 | 426 | ||
430 | snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, | 427 | snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, |
431 | sys_name, evt_name); | 428 | sys_name, evt_name); |
@@ -533,8 +530,7 @@ static enum event_result parse_tracepoint_event(const char **strp, | |||
533 | flags); | 530 | flags); |
534 | } else | 531 | } else |
535 | return parse_single_tracepoint_event(sys_name, evt_name, | 532 | return parse_single_tracepoint_event(sys_name, evt_name, |
536 | evt_length, flags, | 533 | evt_length, attr, strp); |
537 | attr, strp); | ||
538 | } | 534 | } |
539 | 535 | ||
540 | static enum event_result | 536 | static enum event_result |
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 17d6d66ed766..d6ef414075a6 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -761,7 +761,7 @@ static int field_is_string(struct format_field *field) | |||
761 | 761 | ||
762 | static int field_is_dynamic(struct format_field *field) | 762 | static int field_is_dynamic(struct format_field *field) |
763 | { | 763 | { |
764 | if (!strcmp(field->type, "__data_loc")) | 764 | if (!strncmp(field->type, "__data_loc", 10)) |
765 | return 1; | 765 | return 1; |
766 | 766 | ||
767 | return 0; | 767 | return 0; |