aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-10-23 02:23:20 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-23 02:23:20 -0400
commit43315956509ca6913764861ac7dec128b91eb1ec (patch)
tree60fd5647f150a46e63093a41417c2eef3e776b3d /tools/perf/builtin-record.c
parent9bf4e7fba8006d19846fec877b6da0616b2772de (diff)
parent6beba7adbe092e63dfe8d09fbd1e3ec140474a13 (diff)
Merge branch 'perf/core' into perf/probes
Conflicts: tools/perf/Makefile Merge reason: - fix the conflict - pick up the pr_*() infrastructure to queue up dependent patch Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c93
1 files changed, 57 insertions, 36 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 3eeef339c78..ac5ddfff445 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -17,55 +17,51 @@
17#include "util/header.h" 17#include "util/header.h"
18#include "util/event.h" 18#include "util/event.h"
19#include "util/debug.h" 19#include "util/debug.h"
20#include "util/trace-event.h"
21 20
22#include <unistd.h> 21#include <unistd.h>
23#include <sched.h> 22#include <sched.h>
24 23
25#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
26#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
27
28static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 24static int fd[MAX_NR_CPUS][MAX_COUNTERS];
29 25
30static long default_interval = 100000; 26static long default_interval = 0;
31 27
32static int nr_cpus = 0; 28static int nr_cpus = 0;
33static unsigned int page_size; 29static unsigned int page_size;
34static unsigned int mmap_pages = 128; 30static unsigned int mmap_pages = 128;
35static int freq = 0; 31static int freq = 1000;
36static int output; 32static int output;
37static const char *output_name = "perf.data"; 33static const char *output_name = "perf.data";
38static int group = 0; 34static int group = 0;
39static unsigned int realtime_prio = 0; 35static unsigned int realtime_prio = 0;
40static int raw_samples = 0; 36static int raw_samples = 0;
41static int system_wide = 0; 37static int system_wide = 0;
42static int profile_cpu = -1; 38static int profile_cpu = -1;
43static pid_t target_pid = -1; 39static pid_t target_pid = -1;
44static pid_t child_pid = -1; 40static pid_t child_pid = -1;
45static int inherit = 1; 41static int inherit = 1;
46static int force = 0; 42static int force = 0;
47static int append_file = 0; 43static int append_file = 0;
48static int call_graph = 0; 44static int call_graph = 0;
49static int inherit_stat = 0; 45static int inherit_stat = 0;
50static int no_samples = 0; 46static int no_samples = 0;
51static int sample_address = 0; 47static int sample_address = 0;
52static int multiplex = 0; 48static int multiplex = 0;
53static int multiplex_fd = -1; 49static int multiplex_fd = -1;
54 50
55static long samples; 51static long samples = 0;
56static struct timeval last_read; 52static struct timeval last_read;
57static struct timeval this_read; 53static struct timeval this_read;
58 54
59static u64 bytes_written; 55static u64 bytes_written = 0;
60 56
61static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; 57static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
62 58
63static int nr_poll; 59static int nr_poll = 0;
64static int nr_cpu; 60static int nr_cpu = 0;
65 61
66static int file_new = 1; 62static int file_new = 1;
67 63
68struct perf_header *header; 64struct perf_header *header = NULL;
69 65
70struct mmap_data { 66struct mmap_data {
71 int counter; 67 int counter;
@@ -375,9 +371,11 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
375 371
376static void create_counter(int counter, int cpu, pid_t pid) 372static void create_counter(int counter, int cpu, pid_t pid)
377{ 373{
374 char *filter = filters[counter];
378 struct perf_event_attr *attr = attrs + counter; 375 struct perf_event_attr *attr = attrs + counter;
379 struct perf_header_attr *h_attr; 376 struct perf_header_attr *h_attr;
380 int track = !counter; /* only the first counter needs these */ 377 int track = !counter; /* only the first counter needs these */
378 int ret;
381 struct { 379 struct {
382 u64 count; 380 u64 count;
383 u64 time_enabled; 381 u64 time_enabled;
@@ -480,7 +478,6 @@ try_again:
480 multiplex_fd = fd[nr_cpu][counter]; 478 multiplex_fd = fd[nr_cpu][counter];
481 479
482 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) { 480 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
483 int ret;
484 481
485 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd); 482 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
486 assert(ret != -1); 483 assert(ret != -1);
@@ -500,6 +497,16 @@ try_again:
500 } 497 }
501 } 498 }
502 499
500 if (filter != NULL) {
501 ret = ioctl(fd[nr_cpu][counter],
502 PERF_EVENT_IOC_SET_FILTER, filter);
503 if (ret) {
504 error("failed to set filter with %d (%s)\n", errno,
505 strerror(errno));
506 exit(-1);
507 }
508 }
509
503 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE); 510 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
504} 511}
505 512
@@ -566,17 +573,17 @@ static int __cmd_record(int argc, const char **argv)
566 else 573 else
567 header = perf_header__new(); 574 header = perf_header__new();
568 575
569
570 if (raw_samples) { 576 if (raw_samples) {
571 read_tracing_data(attrs, nr_counters); 577 perf_header__feat_trace_info(header);
572 } else { 578 } else {
573 for (i = 0; i < nr_counters; i++) { 579 for (i = 0; i < nr_counters; i++) {
574 if (attrs[i].sample_type & PERF_SAMPLE_RAW) { 580 if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
575 read_tracing_data(attrs, nr_counters); 581 perf_header__feat_trace_info(header);
576 break; 582 break;
577 } 583 }
578 } 584 }
579 } 585 }
586
580 atexit(atexit_header); 587 atexit(atexit_header);
581 588
582 if (!system_wide) { 589 if (!system_wide) {
@@ -623,7 +630,7 @@ static int __cmd_record(int argc, const char **argv)
623 630
624 param.sched_priority = realtime_prio; 631 param.sched_priority = realtime_prio;
625 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 632 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
626 printf("Could not set realtime priority.\n"); 633 pr_err("Could not set realtime priority.\n");
627 exit(-1); 634 exit(-1);
628 } 635 }
629 } 636 }
@@ -677,6 +684,8 @@ static const struct option options[] = {
677 OPT_CALLBACK('e', "event", NULL, "event", 684 OPT_CALLBACK('e', "event", NULL, "event",
678 "event selector. use 'perf list' to list available events", 685 "event selector. use 'perf list' to list available events",
679 parse_events), 686 parse_events),
687 OPT_CALLBACK(0, "filter", NULL, "filter",
688 "event filter", parse_filter),
680 OPT_INTEGER('p', "pid", &target_pid, 689 OPT_INTEGER('p', "pid", &target_pid,
681 "record events on existing pid"), 690 "record events on existing pid"),
682 OPT_INTEGER('r', "realtime", &realtime_prio, 691 OPT_INTEGER('r', "realtime", &realtime_prio,
@@ -731,6 +740,18 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
731 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES; 740 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
732 } 741 }
733 742
743 /*
744 * User specified count overrides default frequency.
745 */
746 if (default_interval)
747 freq = 0;
748 else if (freq) {
749 default_interval = freq;
750 } else {
751 fprintf(stderr, "frequency and count are zero, aborting\n");
752 exit(EXIT_FAILURE);
753 }
754
734 for (counter = 0; counter < nr_counters; counter++) { 755 for (counter = 0; counter < nr_counters; counter++) {
735 if (attrs[counter].sample_period) 756 if (attrs[counter].sample_period)
736 continue; 757 continue;