]> git.karo-electronics.de Git - linux-beck.git/blobdiff - tools/perf/builtin-record.c
perf tools: Bump version to 0.0.2
[linux-beck.git] / tools / perf / builtin-record.c
index 99a12fe86e9fe4010f49439a4c154ac7ac5f6de5..3eeef339c787bdb414a0faba3e31d02a6efa2a02 100644 (file)
@@ -41,6 +41,7 @@ static int                    raw_samples                     = 0;
 static int                     system_wide                     = 0;
 static int                     profile_cpu                     = -1;
 static pid_t                   target_pid                      = -1;
+static pid_t                   child_pid                       = -1;
 static int                     inherit                         = 1;
 static int                     force                           = 0;
 static int                     append_file                     = 0;
@@ -48,6 +49,8 @@ static int                    call_graph                      = 0;
 static int                     inherit_stat                    = 0;
 static int                     no_samples                      = 0;
 static int                     sample_address                  = 0;
+static int                     multiplex                       = 0;
+static int                     multiplex_fd                    = -1;
 
 static long                    samples;
 static struct timeval          last_read;
@@ -75,7 +78,7 @@ static struct mmap_data               mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static unsigned long mmap_read_head(struct mmap_data *md)
 {
-       struct perf_counter_mmap_page *pc = md->base;
+       struct perf_event_mmap_page *pc = md->base;
        long head;
 
        head = pc->data_head;
@@ -86,7 +89,7 @@ static unsigned long mmap_read_head(struct mmap_data *md)
 
 static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
 {
-       struct perf_counter_mmap_page *pc = md->base;
+       struct perf_event_mmap_page *pc = md->base;
 
        /*
         * ensure all reads are done before we write the tail out.
@@ -182,6 +185,9 @@ static void sig_handler(int sig)
 
 static void sig_atexit(void)
 {
+       if (child_pid != -1)
+               kill(child_pid, SIGTERM);
+
        if (signr == -1)
                return;
 
@@ -231,7 +237,7 @@ static pid_t pid_synthesize_comm_event(pid_t pid, int full)
                }
        }
 
-       comm_ev.header.type = PERF_EVENT_COMM;
+       comm_ev.header.type = PERF_RECORD_COMM;
        size = ALIGN(size, sizeof(u64));
        comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
 
@@ -286,7 +292,7 @@ static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
        while (1) {
                char bf[BUFSIZ], *pbf = bf;
                struct mmap_event mmap_ev = {
-                       .header = { .type = PERF_EVENT_MMAP },
+                       .header = { .type = PERF_RECORD_MMAP },
                };
                int n;
                size_t size;
@@ -353,7 +359,7 @@ static void synthesize_all(void)
 
 static int group_fd;
 
-static struct perf_header_attr *get_header_attr(struct perf_counter_attr *a, int nr)
+static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
 {
        struct perf_header_attr *h_attr;
 
@@ -369,7 +375,7 @@ static struct perf_header_attr *get_header_attr(struct perf_counter_attr *a, int
 
 static void create_counter(int counter, int cpu, pid_t pid)
 {
-       struct perf_counter_attr *attr = attrs + counter;
+       struct perf_event_attr *attr = attrs + counter;
        struct perf_header_attr *h_attr;
        int track = !counter; /* only the first counter needs these */
        struct {
@@ -415,7 +421,7 @@ static void create_counter(int counter, int cpu, pid_t pid)
        attr->disabled          = 1;
 
 try_again:
-       fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0);
+       fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0);
 
        if (fd[nr_cpu][counter] < 0) {
                int err = errno;
@@ -442,7 +448,7 @@ try_again:
                printf("\n");
                error("perfcounter syscall returned with %d (%s)\n",
                        fd[nr_cpu][counter], strerror(err));
-               die("No CONFIG_PERF_COUNTERS=y kernel support configured?\n");
+               die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
                exit(-1);
        }
 
@@ -470,22 +476,31 @@ try_again:
         */
        if (group && group_fd == -1)
                group_fd = fd[nr_cpu][counter];
+       if (multiplex && multiplex_fd == -1)
+               multiplex_fd = fd[nr_cpu][counter];
 
-       event_array[nr_poll].fd = fd[nr_cpu][counter];
-       event_array[nr_poll].events = POLLIN;
-       nr_poll++;
-
-       mmap_array[nr_cpu][counter].counter = counter;
-       mmap_array[nr_cpu][counter].prev = 0;
-       mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
-       mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                       PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
-       if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
-               error("failed to mmap with %d (%s)\n", errno, strerror(errno));
-               exit(-1);
+       if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
+               int ret;
+
+               ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
+               assert(ret != -1);
+       } else {
+               event_array[nr_poll].fd = fd[nr_cpu][counter];
+               event_array[nr_poll].events = POLLIN;
+               nr_poll++;
+
+               mmap_array[nr_cpu][counter].counter = counter;
+               mmap_array[nr_cpu][counter].prev = 0;
+               mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
+               mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
+                               PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
+               if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
+                       error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+                       exit(-1);
+               }
        }
 
-       ioctl(fd[nr_cpu][counter], PERF_COUNTER_IOC_ENABLE);
+       ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
 }
 
 static void open_counters(int cpu, pid_t pid)
@@ -513,6 +528,7 @@ static int __cmd_record(int argc, const char **argv)
        pid_t pid = 0;
        int flags;
        int ret;
+       unsigned long waking = 0;
 
        page_size = sysconf(_SC_PAGE_SIZE);
        nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@@ -598,6 +614,8 @@ static int __cmd_record(int argc, const char **argv)
                                exit(-1);
                        }
                }
+
+               child_pid = pid;
        }
 
        if (realtime_prio) {
@@ -614,17 +632,29 @@ static int __cmd_record(int argc, const char **argv)
                int hits = samples;
 
                for (i = 0; i < nr_cpu; i++) {
-                       for (counter = 0; counter < nr_counters; counter++)
-                               mmap_read(&mmap_array[i][counter]);
+                       for (counter = 0; counter < nr_counters; counter++) {
+                               if (mmap_array[i][counter].base)
+                                       mmap_read(&mmap_array[i][counter]);
+                       }
                }
 
                if (hits == samples) {
                        if (done)
                                break;
-                       ret = poll(event_array, nr_poll, 100);
+                       ret = poll(event_array, nr_poll, -1);
+                       waking++;
+               }
+
+               if (done) {
+                       for (i = 0; i < nr_cpu; i++) {
+                               for (counter = 0; counter < nr_counters; counter++)
+                                       ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE);
+                       }
                }
        }
 
+       fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
+
        /*
         * Approximate RIP event size: 24 bytes.
         */
@@ -681,6 +711,8 @@ static const struct option options[] = {
                    "Sample addresses"),
        OPT_BOOLEAN('n', "no-samples", &no_samples,
                    "don't sample"),
+       OPT_BOOLEAN('M', "multiplex", &multiplex,
+                   "multiplex counter output in a single channel"),
        OPT_END()
 };