mm/migrate: correct failure handling if !hugepage_migration_support()
[firefly-linux-kernel-4.4.55.git] / tools / perf / builtin-record.c
index ea7c3060e8e7e231d681a9f6b8181d48be64b3f1..3c394bf16fa8cd86ce01d3d5852bab8a078f5ae4 100644 (file)
@@ -183,7 +183,7 @@ static int record__open(struct record *rec)
 
        perf_evlist__config(evlist, opts);
 
-       list_for_each_entry(pos, &evlist->entries, node) {
+       evlist__for_each(evlist, pos) {
 try_again:
                if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
                        if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
@@ -324,7 +324,6 @@ out:
 
 static void record__init_features(struct record *rec)
 {
-       struct perf_evlist *evsel_list = rec->evlist;
        struct perf_session *session = rec->session;
        int feat;
 
@@ -334,7 +333,7 @@ static void record__init_features(struct record *rec)
        if (rec->no_buildid)
                perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
 
-       if (!have_tracepoints(&evsel_list->entries))
+       if (!have_tracepoints(&rec->evlist->entries))
                perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
 
        if (!rec->opts.branch_stack)
@@ -365,7 +364,6 @@ 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_evlist *evsel_list = rec->evlist;
        struct perf_data_file *file = &rec->file;
        struct perf_session *session;
        bool disabled = false;
@@ -388,7 +386,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
        record__init_features(rec);
 
        if (forks) {
-               err = perf_evlist__prepare_workload(evsel_list, &opts->target,
+               err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
                                                    argv, file->is_pipe,
                                                    workload_exec_failed_signal);
                if (err < 0) {
@@ -402,7 +400,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                goto out_delete_session;
        }
 
-       if (!evsel_list->nr_groups)
+       if (!rec->evlist->nr_groups)
                perf_header__clear_feat(&session->header, HEADER_GROUP_DESC);
 
        /*
@@ -415,7 +413,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                if (err < 0)
                        goto out_delete_session;
        } else {
-               err = perf_session__write_header(session, evsel_list,
+               err = perf_session__write_header(session, rec->evlist,
                                                 file->fd, false);
                if (err < 0)
                        goto out_delete_session;
@@ -439,7 +437,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                        goto out_delete_session;
                }
 
-               if (have_tracepoints(&evsel_list->entries)) {
+               if (have_tracepoints(&rec->evlist->entries)) {
                        /*
                         * FIXME err <= 0 here actually means that
                         * there were no tracepoints so its not really
@@ -448,7 +446,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                         * return this more properly and also
                         * propagate errors that now are calling die()
                         */
-                       err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
+                       err = perf_event__synthesize_tracing_data(tool, file->fd, rec->evlist,
                                                                  process_synthesized_event);
                        if (err <= 0) {
                                pr_err("Couldn't record tracing data.\n");
@@ -480,7 +478,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                                         perf_event__synthesize_guest_os, tool);
        }
 
-       err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads,
+       err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
                                            process_synthesized_event, opts->sample_address);
        if (err != 0)
                goto out_delete_session;
@@ -501,14 +499,19 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
         * (apart from group members) have enable_on_exec=1 set,
         * so don't spoil it by prematurely enabling them.
         */
-       if (!target__none(&opts->target))
-               perf_evlist__enable(evsel_list);
+       if (!target__none(&opts->target) && !opts->initial_delay)
+               perf_evlist__enable(rec->evlist);
 
        /*
         * Let the child rip
         */
        if (forks)
-               perf_evlist__start_workload(evsel_list);
+               perf_evlist__start_workload(rec->evlist);
+
+       if (opts->initial_delay) {
+               usleep(opts->initial_delay * 1000);
+               perf_evlist__enable(rec->evlist);
+       }
 
        for (;;) {
                int hits = rec->samples;
@@ -521,7 +524,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                if (hits == rec->samples) {
                        if (done)
                                break;
-                       err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
+                       err = poll(rec->evlist->pollfd, rec->evlist->nr_fds, -1);
                        waking++;
                }
 
@@ -531,7 +534,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                 * disable events in this case.
                 */
                if (done && !disabled && !target__none(&opts->target)) {
-                       perf_evlist__disable(evsel_list);
+                       perf_evlist__disable(rec->evlist);
                        disabled = true;
                }
        }
@@ -835,7 +838,7 @@ const struct option record_options[] = {
                    "record events on existing thread id"),
        OPT_INTEGER('r', "realtime", &record.realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
-       OPT_BOOLEAN('D', "no-delay", &record.opts.no_delay,
+       OPT_BOOLEAN(0, "no-buffering", &record.opts.no_buffering,
                    "collect data without buffering"),
        OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples,
                    "collect raw sample records from all opened counters"),
@@ -879,6 +882,8 @@ const struct option record_options[] = {
        OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
                     "monitor event in cgroup name only",
                     parse_cgroups),
+       OPT_UINTEGER('D', "delay", &record.opts.initial_delay,
+                 "ms to wait before starting measurement after program start"),
        OPT_STRING('u', "uid", &record.opts.target.uid_str, "user",
                   "user to profile"),
 
@@ -901,16 +906,13 @@ const struct option record_options[] = {
 int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        int err = -ENOMEM;
-       struct perf_evlist *evsel_list;
        struct record *rec = &record;
        char errbuf[BUFSIZ];
 
-       evsel_list = perf_evlist__new();
-       if (evsel_list == NULL)
+       rec->evlist = perf_evlist__new();
+       if (rec->evlist == NULL)
                return -ENOMEM;
 
-       rec->evlist = evsel_list;
-
        argc = parse_options(argc, argv, record_options, record_usage,
                            PARSE_OPT_STOP_AT_NON_OPTION);
        if (!argc && target__none(&rec->opts.target))
@@ -937,8 +939,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
        if (rec->no_buildid_cache || rec->no_buildid)
                disable_buildid_cache();
 
-       if (evsel_list->nr_entries == 0 &&
-           perf_evlist__add_default(evsel_list) < 0) {
+       if (rec->evlist->nr_entries == 0 &&
+           perf_evlist__add_default(rec->evlist) < 0) {
                pr_err("Not enough memory for event selector list\n");
                goto out_symbol_exit;
        }
@@ -964,20 +966,15 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
        }
 
        err = -ENOMEM;
-       if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0)
+       if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0)
                usage_with_options(record_usage, record_options);
 
        if (record_opts__config(&rec->opts)) {
                err = -EINVAL;
-               goto out_free_fd;
+               goto out_symbol_exit;
        }
 
        err = __cmd_record(&record, argc, argv);
-
-       perf_evlist__munmap(evsel_list);
-       perf_evlist__close(evsel_list);
-out_free_fd:
-       perf_evlist__delete_maps(evsel_list);
 out_symbol_exit:
        symbol__exit();
        return err;