Merge tag 'libata-5.15-2021-09-11' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / tools / perf / util / evsel.c
index a576d98..54d2513 100644 (file)
@@ -1709,42 +1709,29 @@ static void display_attr(struct perf_event_attr *attr)
        }
 }
 
-static int perf_event_open(struct evsel *evsel,
-                          pid_t pid, int cpu, int group_fd)
+bool evsel__precise_ip_fallback(struct evsel *evsel)
 {
-       int precise_ip = evsel->core.attr.precise_ip;
-       int fd;
-
-       while (1) {
-               pr_debug2_peo("sys_perf_event_open: pid %d  cpu %d  group_fd %d  flags %#lx",
-                         pid, cpu, group_fd, evsel->open_flags);
-
-               fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, group_fd, evsel->open_flags);
-               if (fd >= 0)
-                       break;
-
-               /* Do not try less precise if not requested. */
-               if (!evsel->precise_max)
-                       break;
-
-               /*
-                * We tried all the precise_ip values, and it's
-                * still failing, so leave it to standard fallback.
-                */
-               if (!evsel->core.attr.precise_ip) {
-                       evsel->core.attr.precise_ip = precise_ip;
-                       break;
-               }
+       /* Do not try less precise if not requested. */
+       if (!evsel->precise_max)
+               return false;
 
-               pr_debug2_peo("\nsys_perf_event_open failed, error %d\n", -ENOTSUP);
-               evsel->core.attr.precise_ip--;
-               pr_debug2_peo("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
-               display_attr(&evsel->core.attr);
+       /*
+        * We tried all the precise_ip values, and it's
+        * still failing, so leave it to standard fallback.
+        */
+       if (!evsel->core.attr.precise_ip) {
+               evsel->core.attr.precise_ip = evsel->precise_ip_original;
+               return false;
        }
 
-       return fd;
-}
+       if (!evsel->precise_ip_original)
+               evsel->precise_ip_original = evsel->core.attr.precise_ip;
 
+       evsel->core.attr.precise_ip--;
+       pr_debug2_peo("decreasing precise_ip by one (%d)\n", evsel->core.attr.precise_ip);
+       display_attr(&evsel->core.attr);
+       return true;
+}
 
 static struct perf_cpu_map *empty_cpu_map;
 static struct perf_thread_map *empty_thread_map;
@@ -2004,8 +1991,11 @@ retry_open:
 
                        test_attr__ready();
 
-                       fd = perf_event_open(evsel, pid, cpus->map[cpu],
-                                            group_fd);
+                       pr_debug2_peo("sys_perf_event_open: pid %d  cpu %d  group_fd %d  flags %#lx",
+                               pid, cpus->map[cpu], group_fd, evsel->open_flags);
+
+                       fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[cpu],
+                                               group_fd, evsel->open_flags);
 
                        FD(evsel, cpu, thread) = fd;
 
@@ -2058,6 +2048,9 @@ retry_open:
        return 0;
 
 try_fallback:
+       if (evsel__precise_ip_fallback(evsel))
+               goto retry_open;
+
        if (evsel__ignore_missing_thread(evsel, cpus->nr, cpu, threads, thread, err)) {
                /* We just removed 1 thread, so lower the upper nthreads limit. */
                nthreads--;