]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - tools/perf/util/evsel.c
Merge branch 'tsc2007' into next
[karo-tx-linux.git] / tools / perf / util / evsel.c
index b2365a63db45c16f62c13093f55187f78ffd9c12..04e536ae4d88423e3c05a98fd1bd97ff64379b14 100644 (file)
@@ -990,6 +990,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
         * it overloads any global configuration.
         */
        apply_config_terms(evsel, opts);
+
+       evsel->ignore_missing_thread = opts->ignore_missing_thread;
 }
 
 static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
@@ -1419,6 +1421,33 @@ static int __open_attr__fprintf(FILE *fp, const char *name, const char *val,
        return fprintf(fp, "  %-32s %s\n", name, val);
 }
 
+static bool ignore_missing_thread(struct perf_evsel *evsel,
+                                 struct thread_map *threads,
+                                 int thread, int err)
+{
+       if (!evsel->ignore_missing_thread)
+               return false;
+
+       /* The system wide setup does not work with threads. */
+       if (evsel->system_wide)
+               return false;
+
+       /* The -ESRCH is perf event syscall errno for pid's not found. */
+       if (err != -ESRCH)
+               return false;
+
+       /* If there's only one thread, let it fail. */
+       if (threads->nr == 1)
+               return false;
+
+       if (thread_map__remove(threads, thread))
+               return false;
+
+       pr_warning("WARNING: Ignored open failure for pid %d\n",
+                  thread_map__pid(threads, thread));
+       return true;
+}
+
 static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
                              struct thread_map *threads)
 {
@@ -1474,7 +1503,7 @@ retry_sample_id:
        for (cpu = 0; cpu < cpus->nr; cpu++) {
 
                for (thread = 0; thread < nthreads; thread++) {
-                       int group_fd;
+                       int fd, group_fd;
 
                        if (!evsel->cgrp && !evsel->system_wide)
                                pid = thread_map__pid(threads, thread);
@@ -1484,21 +1513,37 @@ retry_open:
                        pr_debug2("sys_perf_event_open: pid %d  cpu %d  group_fd %d  flags %#lx",
                                  pid, cpus->map[cpu], group_fd, flags);
 
-                       FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr,
-                                                                    pid,
-                                                                    cpus->map[cpu],
-                                                                    group_fd, flags);
-                       if (FD(evsel, cpu, thread) < 0) {
+                       fd = sys_perf_event_open(&evsel->attr, pid, cpus->map[cpu],
+                                                group_fd, flags);
+
+                       FD(evsel, cpu, thread) = fd;
+
+                       if (fd < 0) {
                                err = -errno;
+
+                               if (ignore_missing_thread(evsel, threads, thread, err)) {
+                                       /*
+                                        * We just removed 1 thread, so take a step
+                                        * back on thread index and lower the upper
+                                        * nthreads limit.
+                                        */
+                                       nthreads--;
+                                       thread--;
+
+                                       /* ... and pretend like nothing have happened. */
+                                       err = 0;
+                                       continue;
+                               }
+
                                pr_debug2("\nsys_perf_event_open failed, error %d\n",
                                          err);
                                goto try_fallback;
                        }
 
-                       pr_debug2(" = %d\n", FD(evsel, cpu, thread));
+                       pr_debug2(" = %d\n", fd);
 
                        if (evsel->bpf_fd >= 0) {
-                               int evt_fd = FD(evsel, cpu, thread);
+                               int evt_fd = fd;
                                int bpf_fd = evsel->bpf_fd;
 
                                err = ioctl(evt_fd,