perf record: Add a fallback to the reference relocation symbol
[safe/jmp/linux-2.6] / tools / perf / builtin-record.c
index 7bb9ca1..f1411e9 100644 (file)
@@ -5,10 +5,13 @@
  * (or a CPU, or a PID) into the perf.data output file - for
  * later analysis via perf report.
  */
+#define _FILE_OFFSET_BITS 64
+
 #include "builtin.h"
 
 #include "perf.h"
 
+#include "util/build-id.h"
 #include "util/util.h"
 #include "util/parse-options.h"
 #include "util/parse-events.h"
@@ -19,6 +22,7 @@
 #include "util/debug.h"
 #include "util/session.h"
 #include "util/symbol.h"
+#include "util/cpumap.h"
 
 #include <unistd.h>
 #include <sched.h>
@@ -62,6 +66,7 @@ static int                    nr_poll                         =      0;
 static int                     nr_cpu                          =      0;
 
 static int                     file_new                        =      1;
+static off_t                   post_processing_offset;
 
 static struct perf_session     *session;
 
@@ -111,34 +116,10 @@ static void write_output(void *buf, size_t size)
        }
 }
 
-static void write_event(event_t *buf, size_t size)
-{
-       size_t processed_size = buf->header.size;
-       event_t *ev = buf;
-
-       do {
-               /*
-               * Add it to the list of DSOs, so that when we finish this
-                * record session we can pick the available build-ids.
-                */
-               if (ev->header.type == PERF_RECORD_MMAP) {
-                       struct list_head *head = &dsos__user;
-                       if (ev->header.misc == 1)
-                               head = &dsos__kernel;
-                       __dsos__findnew(head, ev->mmap.filename);
-               }
-
-               ev = ((void *)ev) + ev->header.size;
-               processed_size += ev->header.size;
-       } while (processed_size < size);
-
-       write_output(buf, size);
-}
-
 static int process_synthesized_event(event_t *event,
                                     struct perf_session *self __used)
 {
-       write_event(event, event->header.size);
+       write_output(event, event->header.size);
        return 0;
 }
 
@@ -190,14 +171,14 @@ static void mmap_read(struct mmap_data *md)
                size = md->mask + 1 - (old & md->mask);
                old += size;
 
-               write_event(buf, size);
+               write_output(buf, size);
        }
 
        buf = &data[old & md->mask];
        size = head - old;
        old += size;
 
-       write_event(buf, size);
+       write_output(buf, size);
 
        md->prev = old;
        mmap_write_tail(md, old);
@@ -264,6 +245,9 @@ static void create_counter(int counter, int cpu, pid_t pid)
 
        attr->sample_type       |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
 
+       if (nr_counters > 1)
+               attr->sample_type |= PERF_SAMPLE_ID;
+
        if (freq) {
                attr->sample_type       |= PERF_SAMPLE_PERIOD;
                attr->freq              = 1;
@@ -407,10 +391,24 @@ static void open_counters(int cpu, pid_t pid)
        nr_cpu++;
 }
 
+static int process_buildids(void)
+{
+       u64 size = lseek(output, 0, SEEK_CUR);
+
+       if (size == 0)
+               return 0;
+
+       session->fd = output;
+       return __perf_session__process_events(session, post_processing_offset,
+                                             size - post_processing_offset,
+                                             size, &build_id__mark_dso_hit_ops);
+}
+
 static void atexit_header(void)
 {
        session->header.data_size += bytes_written;
 
+       process_buildids();
        perf_header__write(&session->header, output, true);
 }
 
@@ -427,9 +425,6 @@ static int __cmd_record(int argc, const char **argv)
        char buf;
 
        page_size = sysconf(_SC_PAGE_SIZE);
-       nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-       assert(nr_cpus <= MAX_NR_CPUS);
-       assert(nr_cpus >= 0);
 
        atexit(sig_atexit);
        signal(SIGCHLD, sig_handler);
@@ -477,11 +472,6 @@ static int __cmd_record(int argc, const char **argv)
                return -1;
        }
 
-       if (perf_session__create_kernel_maps(session) < 0) {
-               pr_err("Problems creating kernel maps\n");
-               return -1;
-       }
-
        if (!file_new) {
                err = perf_header__read(&session->header, output);
                if (err < 0)
@@ -558,8 +548,9 @@ static int __cmd_record(int argc, const char **argv)
        if ((!system_wide && !inherit) || profile_cpu != -1) {
                open_counters(profile_cpu, target_pid);
        } else {
+               nr_cpus = read_cpu_map();
                for (i = 0; i < nr_cpus; i++)
-                       open_counters(i, target_pid);
+                       open_counters(cpumap[i], target_pid);
        }
 
        if (file_new) {
@@ -568,8 +559,13 @@ static int __cmd_record(int argc, const char **argv)
                        return err;
        }
 
+       post_processing_offset = lseek(output, 0, SEEK_CUR);
+
        err = event__synthesize_kernel_mmap(process_synthesized_event,
                                            session, "_text");
+       if (err < 0)
+               err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                                   session, "_stext");
        if (err < 0) {
                pr_err("Couldn't record kernel reference relocation symbol.\n");
                return err;
@@ -582,7 +578,7 @@ static int __cmd_record(int argc, const char **argv)
        }
 
        if (!system_wide && profile_cpu == -1)
-               event__synthesize_thread(pid, process_synthesized_event,
+               event__synthesize_thread(target_pid, process_synthesized_event,
                                         session);
        else
                event__synthesize_threads(process_synthesized_event, session);