Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / tools / perf / builtin-stat.c
index 32d930e..1e5e9b2 100644 (file)
@@ -182,8 +182,8 @@ static int                  run_count                       =  1;
 static bool                    no_inherit                      = false;
 static bool                    scale                           =  true;
 static bool                    no_aggr                         = false;
-static pid_t                   target_pid                      = -1;
-static pid_t                   target_tid                      = -1;
+static const char              *target_pid;
+static const char              *target_tid;
 static pid_t                   child_pid                       = -1;
 static bool                    null_run                        =  false;
 static int                     detailed_run                    =  0;
@@ -283,6 +283,8 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,
 {
        struct perf_event_attr *attr = &evsel->attr;
        struct xyarray *group_fd = NULL;
+       bool exclude_guest_missing = false;
+       int ret;
 
        if (group && evsel != first)
                group_fd = first->fd;
@@ -293,16 +295,39 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,
 
        attr->inherit = !no_inherit;
 
-       if (system_wide)
-               return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
+retry:
+       if (exclude_guest_missing)
+               evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
+
+       if (system_wide) {
+               ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
                                                group, group_fd);
-       if (target_pid == -1 && target_tid == -1) {
+               if (ret)
+                       goto check_ret;
+               return 0;
+       }
+
+       if (!target_pid && !target_tid && (!group || evsel == first)) {
                attr->disabled = 1;
                attr->enable_on_exec = 1;
        }
 
-       return perf_evsel__open_per_thread(evsel, evsel_list->threads,
-                                          group, group_fd);
+       ret = perf_evsel__open_per_thread(evsel, evsel_list->threads,
+                                         group, group_fd);
+       if (!ret)
+               return 0;
+       /* fall through */
+check_ret:
+       if (ret && errno == EINVAL) {
+               if (!exclude_guest_missing &&
+                   (evsel->attr.exclude_guest || evsel->attr.exclude_host)) {
+                       pr_debug("Old kernel, cannot exclude "
+                                "guest or host samples.\n");
+                       exclude_guest_missing = true;
+                       goto retry;
+               }
+       }
+       return ret;
 }
 
 /*
@@ -446,7 +471,7 @@ static int run_perf_stat(int argc __used, const char **argv)
                        exit(-1);
                }
 
-               if (target_tid == -1 && target_pid == -1 && !system_wide)
+               if (!target_tid && !target_pid && !system_wide)
                        evsel_list->threads->map[0] = child_pid;
 
                /*
@@ -463,8 +488,13 @@ static int run_perf_stat(int argc __used, const char **argv)
 
        list_for_each_entry(counter, &evsel_list->entries, node) {
                if (create_perf_stat_counter(counter, first) < 0) {
+                       /*
+                        * PPC returns ENXIO for HW counters until 2.6.37
+                        * (behavior changed with commit b0a873e).
+                        */
                        if (errno == EINVAL || errno == ENOSYS ||
-                           errno == ENOENT || errno == EOPNOTSUPP) {
+                           errno == ENOENT || errno == EOPNOTSUPP ||
+                           errno == ENXIO) {
                                if (verbose)
                                        ui__warning("%s event is not supported by the kernel.\n",
                                                    event_name(counter));
@@ -576,6 +606,8 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
        if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
                fprintf(output, " # %8.3f CPUs utilized          ",
                        avg / avg_stats(&walltime_nsecs_stats));
+       else
+               fprintf(output, "                                   ");
 }
 
 /* used for get_ratio_color() */
@@ -966,14 +998,14 @@ static void print_stat(int argc, const char **argv)
        if (!csv_output) {
                fprintf(output, "\n");
                fprintf(output, " Performance counter stats for ");
-               if(target_pid == -1 && target_tid == -1) {
+               if (!target_pid && !target_tid) {
                        fprintf(output, "\'%s", argv[0]);
                        for (i = 1; i < argc; i++)
                                fprintf(output, " %s", argv[i]);
-               } else if (target_pid != -1)
-                       fprintf(output, "process id \'%d", target_pid);
+               } else if (target_pid)
+                       fprintf(output, "process id \'%s", target_pid);
                else
-                       fprintf(output, "thread id \'%d", target_tid);
+                       fprintf(output, "thread id \'%s", target_tid);
 
                fprintf(output, "\'");
                if (run_count > 1)
@@ -1047,10 +1079,10 @@ static const struct option options[] = {
                     "event filter", parse_filter),
        OPT_BOOLEAN('i', "no-inherit", &no_inherit,
                    "child tasks do not inherit counters"),
-       OPT_INTEGER('p', "pid", &target_pid,
-                   "stat events on existing process id"),
-       OPT_INTEGER('t', "tid", &target_tid,
-                   "stat events on existing thread id"),
+       OPT_STRING('p', "pid", &target_pid, "pid",
+                  "stat events on existing process id"),
+       OPT_STRING('t', "tid", &target_tid, "tid",
+                  "stat events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                    "system-wide collection from all CPUs"),
        OPT_BOOLEAN('g', "group", &group,
@@ -1188,7 +1220,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
        } else if (big_num_opt == 0) /* User passed --no-big-num */
                big_num = false;
 
-       if (!argc && target_pid == -1 && target_tid == -1)
+       if (!argc && !target_pid && !target_tid)
                usage_with_options(stat_usage, options);
        if (run_count <= 0)
                usage_with_options(stat_usage, options);
@@ -1204,10 +1236,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
        if (add_default_attributes())
                goto out;
 
-       if (target_pid != -1)
+       if (target_pid)
                target_tid = target_pid;
 
-       evsel_list->threads = thread_map__new(target_pid, target_tid, UINT_MAX);
+       evsel_list->threads = thread_map__new_str(target_pid,
+                                                 target_tid, UINT_MAX);
        if (evsel_list->threads == NULL) {
                pr_err("Problems finding threads of monitor\n");
                usage_with_options(stat_usage, options);