Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / tools / perf / builtin-record.c
index 06c4dca..0338b81 100644 (file)
@@ -1255,6 +1255,7 @@ static int record__synthesize_workload(struct record *rec, bool tail)
 {
        int err;
        struct perf_thread_map *thread_map;
+       bool needs_mmap = rec->opts.synth & PERF_SYNTH_MMAP;
 
        if (rec->opts.tail_synthesize != tail)
                return 0;
@@ -1266,6 +1267,7 @@ static int record__synthesize_workload(struct record *rec, bool tail)
        err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
                                                 process_synthesized_event,
                                                 &rec->session->machines.host,
+                                                needs_mmap,
                                                 rec->opts.sample_address);
        perf_thread_map__put(thread_map);
        return err;
@@ -1409,7 +1411,7 @@ static int record__synthesize(struct record *rec, bool tail)
                goto out;
 
        /* Synthesize id_index before auxtrace_info */
-       if (rec->opts.auxtrace_sample_mode) {
+       if (rec->opts.auxtrace_sample_mode || rec->opts.full_auxtrace) {
                err = perf_event__synthesize_id_index(tool,
                                                      process_synthesized_event,
                                                      session->evlist, machine);
@@ -1470,19 +1472,26 @@ static int record__synthesize(struct record *rec, bool tail)
        if (err < 0)
                pr_warning("Couldn't synthesize bpf events.\n");
 
-       err = perf_event__synthesize_cgroups(tool, process_synthesized_event,
-                                            machine);
-       if (err < 0)
-               pr_warning("Couldn't synthesize cgroup events.\n");
+       if (rec->opts.synth & PERF_SYNTH_CGROUP) {
+               err = perf_event__synthesize_cgroups(tool, process_synthesized_event,
+                                                    machine);
+               if (err < 0)
+                       pr_warning("Couldn't synthesize cgroup events.\n");
+       }
 
        if (rec->opts.nr_threads_synthesize > 1) {
                perf_set_multithreaded();
                f = process_locked_synthesized_event;
        }
 
-       err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads,
-                                           f, opts->sample_address,
-                                           rec->opts.nr_threads_synthesize);
+       if (rec->opts.synth & PERF_SYNTH_TASK) {
+               bool needs_mmap = rec->opts.synth & PERF_SYNTH_MMAP;
+
+               err = __machine__synthesize_threads(machine, tool, &opts->target,
+                                                   rec->evlist->core.threads,
+                                                   f, needs_mmap, opts->sample_address,
+                                                   rec->opts.nr_threads_synthesize);
+       }
 
        if (rec->opts.nr_threads_synthesize > 1)
                perf_set_singlethreaded();
@@ -2391,6 +2400,26 @@ static int process_timestamp_boundary(struct perf_tool *tool,
        return 0;
 }
 
+static int parse_record_synth_option(const struct option *opt,
+                                    const char *str,
+                                    int unset __maybe_unused)
+{
+       struct record_opts *opts = opt->value;
+       char *p = strdup(str);
+
+       if (p == NULL)
+               return -1;
+
+       opts->synth = parse_synth_opt(p);
+       free(p);
+
+       if (opts->synth < 0) {
+               pr_err("Invalid synth option: %s\n", str);
+               return -1;
+       }
+       return 0;
+}
+
 /*
  * XXX Ideally would be local to cmd_record() and passed to a record__new
  * because we need to have access to it in record__exit, that is called
@@ -2416,6 +2445,7 @@ static struct record record = {
                .nr_threads_synthesize = 1,
                .ctl_fd              = -1,
                .ctl_fd_ack          = -1,
+               .synth               = PERF_SYNTH_ALL,
        },
        .tool = {
                .sample         = process_sample_event,
@@ -2631,6 +2661,8 @@ static struct option __record_options[] = {
                     "\t\t\t  Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n"
                     "\t\t\t  Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.",
                      parse_control_option),
+       OPT_CALLBACK(0, "synth", &record.opts, "no|all|task|mmap|cgroup",
+                    "Fine-tune event synthesis: default=all", parse_record_synth_option),
        OPT_END()
 };
 
@@ -2680,6 +2712,10 @@ int cmd_record(int argc, const char **argv)
        if (quiet)
                perf_quiet_option();
 
+       err = symbol__validate_sym_arguments();
+       if (err)
+               return err;
+
        /* Make system wide (-a) the default target. */
        if (!argc && target__none(&rec->opts.target))
                rec->opts.target.system_wide = true;
@@ -2757,7 +2793,7 @@ int cmd_record(int argc, const char **argv)
 
        if (rec->opts.affinity != PERF_AFFINITY_SYS) {
                rec->affinity_mask.nbits = cpu__max_cpu();
-               rec->affinity_mask.bits = bitmap_alloc(rec->affinity_mask.nbits);
+               rec->affinity_mask.bits = bitmap_zalloc(rec->affinity_mask.nbits);
                if (!rec->affinity_mask.bits) {
                        pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits);
                        err = -ENOMEM;