]> Git Repo - linux.git/blobdiff - tools/perf/builtin-record.c
Merge branch 'linus' into perf/core, to fix conflicts
[linux.git] / tools / perf / builtin-record.c
index 0c95ffefb6ccdbbee39b49a60f0efd8b3977a234..3d7f33e19df28d90c7e33dcc37ea823197de6731 100644 (file)
@@ -67,7 +67,7 @@ struct record {
        struct perf_tool        tool;
        struct record_opts      opts;
        u64                     bytes_written;
-       struct perf_data_file   file;
+       struct perf_data        data;
        struct auxtrace_record  *itr;
        struct perf_evlist      *evlist;
        struct perf_session     *session;
@@ -108,7 +108,7 @@ static bool switch_output_time(struct record *rec)
 
 static int record__write(struct record *rec, void *bf, size_t size)
 {
-       if (perf_data_file__write(rec->session->file, bf, size) < 0) {
+       if (perf_data__write(rec->session->data, bf, size) < 0) {
                pr_err("failed to write perf data, error: %m\n");
                return -1;
        }
@@ -130,107 +130,12 @@ static int process_synthesized_event(struct perf_tool *tool,
        return record__write(rec, event, event->header.size);
 }
 
-static int
-backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
+static int record__pushfn(void *to, void *bf, size_t size)
 {
-       struct perf_event_header *pheader;
-       u64 evt_head = head;
-       int size = mask + 1;
-
-       pr_debug2("backward_rb_find_range: buf=%p, head=%"PRIx64"\n", buf, head);
-       pheader = (struct perf_event_header *)(buf + (head & mask));
-       *start = head;
-       while (true) {
-               if (evt_head - head >= (unsigned int)size) {
-                       pr_debug("Finished reading backward ring buffer: rewind\n");
-                       if (evt_head - head > (unsigned int)size)
-                               evt_head -= pheader->size;
-                       *end = evt_head;
-                       return 0;
-               }
-
-               pheader = (struct perf_event_header *)(buf + (evt_head & mask));
-
-               if (pheader->size == 0) {
-                       pr_debug("Finished reading backward ring buffer: get start\n");
-                       *end = evt_head;
-                       return 0;
-               }
-
-               evt_head += pheader->size;
-               pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
-       }
-       WARN_ONCE(1, "Shouldn't get here\n");
-       return -1;
-}
-
-static int
-rb_find_range(void *data, int mask, u64 head, u64 old,
-             u64 *start, u64 *end, bool backward)
-{
-       if (!backward) {
-               *start = old;
-               *end = head;
-               return 0;
-       }
-
-       return backward_rb_find_range(data, mask, head, start, end);
-}
-
-static int
-record__mmap_read(struct record *rec, struct perf_mmap *md,
-                 bool overwrite, bool backward)
-{
-       u64 head = perf_mmap__read_head(md);
-       u64 old = md->prev;
-       u64 end = head, start = old;
-       unsigned char *data = md->base + page_size;
-       unsigned long size;
-       void *buf;
-       int rc = 0;
-
-       if (rb_find_range(data, md->mask, head,
-                         old, &start, &end, backward))
-               return -1;
-
-       if (start == end)
-               return 0;
+       struct record *rec = to;
 
        rec->samples++;
-
-       size = end - start;
-       if (size > (unsigned long)(md->mask) + 1) {
-               WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
-
-               md->prev = head;
-               perf_mmap__consume(md, overwrite || backward);
-               return 0;
-       }
-
-       if ((start & md->mask) + size != (end & md->mask)) {
-               buf = &data[start & md->mask];
-               size = md->mask + 1 - (start & md->mask);
-               start += size;
-
-               if (record__write(rec, buf, size) < 0) {
-                       rc = -1;
-                       goto out;
-               }
-       }
-
-       buf = &data[start & md->mask];
-       size = end - start;
-       start += size;
-
-       if (record__write(rec, buf, size) < 0) {
-               rc = -1;
-               goto out;
-       }
-
-       md->prev = head;
-       perf_mmap__consume(md, overwrite || backward);
-out:
-       return rc;
+       return record__write(rec, bf, size);
 }
 
 static volatile int done;
@@ -269,13 +174,13 @@ static int record__process_auxtrace(struct perf_tool *tool,
                                    size_t len1, void *data2, size_t len2)
 {
        struct record *rec = container_of(tool, struct record, tool);
-       struct perf_data_file *file = &rec->file;
+       struct perf_data *data = &rec->data;
        size_t padding;
        u8 pad[8] = {0};
 
-       if (!perf_data_file__is_pipe(file)) {
+       if (!perf_data__is_pipe(data)) {
                off_t file_offset;
-               int fd = perf_data_file__fd(file);
+               int fd = perf_data__fd(data);
                int err;
 
                file_offset = lseek(fd, 0, SEEK_CUR);
@@ -494,10 +399,10 @@ static int process_sample_event(struct perf_tool *tool,
 
 static int process_buildids(struct record *rec)
 {
-       struct perf_data_file *file  = &rec->file;
+       struct perf_data *data = &rec->data;
        struct perf_session *session = rec->session;
 
-       if (file->size == 0)
+       if (data->size == 0)
                return 0;
 
        /*
@@ -577,8 +482,7 @@ static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evli
                struct auxtrace_mmap *mm = &maps[i].auxtrace_mmap;
 
                if (maps[i].base) {
-                       if (record__mmap_read(rec, &maps[i],
-                                             evlist->overwrite, backward) != 0) {
+                       if (perf_mmap__push(&maps[i], evlist->overwrite, backward, rec, record__pushfn) != 0) {
                                rc = -1;
                                goto out;
                        }
@@ -641,14 +545,14 @@ static void record__init_features(struct record *rec)
 static void
 record__finish_output(struct record *rec)
 {
-       struct perf_data_file *file = &rec->file;
-       int fd = perf_data_file__fd(file);
+       struct perf_data *data = &rec->data;
+       int fd = perf_data__fd(data);
 
-       if (file->is_pipe)
+       if (data->is_pipe)
                return;
 
        rec->session->header.data_size += rec->bytes_written;
-       file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR);
+       data->size = lseek(perf_data__fd(data), 0, SEEK_CUR);
 
        if (!rec->no_buildid) {
                process_buildids(rec);
@@ -687,7 +591,7 @@ static int record__synthesize(struct record *rec, bool tail);
 static int
 record__switch_output(struct record *rec, bool at_exit)
 {
-       struct perf_data_file *file = &rec->file;
+       struct perf_data *data = &rec->data;
        int fd, err;
 
        /* Same Size:      "2015122520103046"*/
@@ -705,7 +609,7 @@ record__switch_output(struct record *rec, bool at_exit)
                return -EINVAL;
        }
 
-       fd = perf_data_file__switch(file, timestamp,
+       fd = perf_data__switch(data, timestamp,
                                    rec->session->header.data_offset,
                                    at_exit);
        if (fd >= 0 && !at_exit) {
@@ -715,7 +619,7 @@ record__switch_output(struct record *rec, bool at_exit)
 
        if (!quiet)
                fprintf(stderr, "[ perf record: Dump %s.%s ]\n",
-                       file->path, timestamp);
+                       data->file.path, timestamp);
 
        /* Output tracking events */
        if (!at_exit) {
@@ -790,16 +694,16 @@ static int record__synthesize(struct record *rec, bool tail)
 {
        struct perf_session *session = rec->session;
        struct machine *machine = &session->machines.host;
-       struct perf_data_file *file = &rec->file;
+       struct perf_data *data = &rec->data;
        struct record_opts *opts = &rec->opts;
        struct perf_tool *tool = &rec->tool;
-       int fd = perf_data_file__fd(file);
+       int fd = perf_data__fd(data);
        int err = 0;
 
        if (rec->opts.tail_synthesize != tail)
                return 0;
 
-       if (file->is_pipe) {
+       if (data->is_pipe) {
                err = perf_event__synthesize_features(
                        tool, session, rec->evlist, process_synthesized_event);
                if (err < 0) {
@@ -864,7 +768,7 @@ static int record__synthesize(struct record *rec, bool tail)
 
        err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
                                            process_synthesized_event, opts->sample_address,
-                                           opts->proc_map_timeout);
+                                           opts->proc_map_timeout, 1);
 out:
        return err;
 }
@@ -878,7 +782,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
        struct machine *machine;
        struct perf_tool *tool = &rec->tool;
        struct record_opts *opts = &rec->opts;
-       struct perf_data_file *file = &rec->file;
+       struct perf_data *data = &rec->data;
        struct perf_session *session;
        bool disabled = false, draining = false;
        int fd;
@@ -904,20 +808,20 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                signal(SIGUSR2, SIG_IGN);
        }
 
-       session = perf_session__new(file, false, tool);
+       session = perf_session__new(data, false, tool);
        if (session == NULL) {
                pr_err("Perf session creation failed.\n");
                return -1;
        }
 
-       fd = perf_data_file__fd(file);
+       fd = perf_data__fd(data);
        rec->session = session;
 
        record__init_features(rec);
 
        if (forks) {
                err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
-                                                   argv, file->is_pipe,
+                                                   argv, data->is_pipe,
                                                    workload_exec_failed_signal);
                if (err < 0) {
                        pr_err("Couldn't run the workload!\n");
@@ -953,7 +857,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
        if (!rec->evlist->nr_groups)
                perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
 
-       if (file->is_pipe) {
+       if (data->is_pipe) {
                err = perf_header__write_pipe(fd);
                if (err < 0)
                        goto out_child;
@@ -1214,8 +1118,8 @@ out_child:
                        samples[0] = '\0';
 
                fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n",
-                       perf_data_file__size(file) / 1024.0 / 1024.0,
-                       file->path, postfix, samples);
+                       perf_data__size(data) / 1024.0 / 1024.0,
+                       data->file.path, postfix, samples);
        }
 
 out_delete_session:
@@ -1579,7 +1483,7 @@ static struct option __record_options[] = {
        OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
                    "list of cpus to monitor"),
        OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
-       OPT_STRING('o', "output", &record.file.path, "file",
+       OPT_STRING('o', "output", &record.data.file.path, "file",
                    "output file name"),
        OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
                        &record.opts.no_inherit_set,
@@ -1644,6 +1548,9 @@ static struct option __record_options[] = {
        OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
                    "sample selected machine registers on interrupt,"
                    " use -I ? to list register names", parse_regs),
+       OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
+                   "sample selected machine registers on interrupt,"
+                   " use -I ? to list register names", parse_regs),
        OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
                    "Record running/enabled time of read (:S) events"),
        OPT_CALLBACK('k', "clockid", &record.opts,
This page took 0.045756 seconds and 4 git commands to generate.