* 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)
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)
{
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;