aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt4
-rw-r--r--tools/perf/builtin-record.c76
-rw-r--r--tools/perf/util/parse-events.c16
-rw-r--r--tools/perf/util/trace-event-parse.c2
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::
104Collect raw sample records from all opened counters (typically for tracepoint counters). 104Collect raw sample records from all opened counters (default for tracepoint counters).
105 105
106SEE ALSO 106SEE 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
29enum write_mode_t {
30 WRITE_FORCE,
31 WRITE_APPEND
32};
33
29static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; 34static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
30 35
36static unsigned int user_interval = UINT_MAX;
31static long default_interval = 0; 37static long default_interval = 0;
32 38
33static int nr_cpus = 0; 39static int nr_cpus = 0;
34static unsigned int page_size; 40static unsigned int page_size;
35static unsigned int mmap_pages = 128; 41static unsigned int mmap_pages = 128;
42static unsigned int user_freq = UINT_MAX;
36static int freq = 1000; 43static int freq = 1000;
37static int output; 44static int output;
38static int pipe_output = 0; 45static int pipe_output = 0;
@@ -48,8 +55,7 @@ static pid_t *all_tids = NULL;
48static int thread_num = 0; 55static int thread_num = 0;
49static pid_t child_pid = -1; 56static pid_t child_pid = -1;
50static bool inherit = true; 57static bool inherit = true;
51static bool force = false; 58static enum write_mode_t write_mode = WRITE_FORCE;
52static bool append_file = false;
53static bool call_graph = false; 59static bool call_graph = false;
54static bool inherit_stat = false; 60static bool inherit_stat = false;
55static bool no_samples = false; 61static 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
733static bool force, append_file;
734
724static const struct option options[] = { 735static 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
771int cmd_record(int argc, const char **argv, const char *prefix __used) 782int 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
410parse_single_tracepoint_event(char *sys_name, 410parse_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
540static enum event_result 536static 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
762static int field_is_dynamic(struct format_field *field) 762static 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;