perf tools: Move routines that probe for perf API features to separate file
authorArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 5 May 2020 14:49:08 +0000 (11:49 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 5 May 2020 19:35:26 +0000 (16:35 -0300)
Trying to disentangle this a bit further, unfortunately it uses
parse_events(), its interesting to have it separated anyway, so do it.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/x86/util/intel-pt.c
tools/perf/builtin-record.c
tools/perf/util/Build
tools/perf/util/auxtrace.c
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/intel-pt.c
tools/perf/util/perf_api_probe.c [new file with mode: 0644]
tools/perf/util/perf_api_probe.h [new file with mode: 0644]
tools/perf/util/record.c

index 941f814..b8df805 100644 (file)
@@ -23,6 +23,7 @@
 #include "../../util/event.h"
 #include "../../util/evlist.h"
 #include "../../util/evsel.h"
+#include "../../util/perf_api_probe.h"
 #include "../../util/evsel_config.h"
 #include "../../util/pmu.h"
 #include "../../util/cs-etm.h"
index 1643aed..6b88896 100644 (file)
@@ -25,6 +25,7 @@
 #include "../../../util/pmu.h"
 #include "../../../util/debug.h"
 #include "../../../util/auxtrace.h"
+#include "../../../util/perf_api_probe.h"
 #include "../../../util/record.h"
 #include "../../../util/target.h"
 #include "../../../util/tsc.h"
index 2e8011f..bf3a6f7 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/tsc.h"
 #include "util/parse-branch-options.h"
 #include "util/parse-regs-options.h"
+#include "util/perf_api_probe.h"
 #include "util/llvm-utils.h"
 #include "util/bpf-loader.h"
 #include "util/trigger.h"
index c0cf8df..229abef 100644 (file)
@@ -88,6 +88,7 @@ perf-y += counts.o
 perf-y += stat.o
 perf-y += stat-shadow.o
 perf-y += stat-display.o
+perf-y += perf_api_probe.o
 perf-y += record.o
 perf-y += srcline.o
 perf-y += srccode.o
index 33ad333..ac6e099 100644 (file)
@@ -33,6 +33,7 @@
 #include "evsel.h"
 #include "evsel_config.h"
 #include "symbol.h"
+#include "util/perf_api_probe.h"
 #include "util/synthetic-events.h"
 #include "thread_map.h"
 #include "asm/bug.h"
index 82d9f9b..3f7e7d5 100644 (file)
@@ -23,6 +23,7 @@
 #include "asm/bug.h"
 #include "bpf-event.h"
 #include "util/string2.h"
+#include "util/perf_api_probe.h"
 #include <signal.h>
 #include <unistd.h>
 #include <sched.h>
index f5bd5c3..48622e5 100644 (file)
@@ -173,10 +173,6 @@ void evlist__close(struct evlist *evlist);
 struct callchain_param;
 
 void perf_evlist__set_id_pos(struct evlist *evlist);
-bool perf_can_sample_identifier(void);
-bool perf_can_record_switch_events(void);
-bool perf_can_record_cpu_wide(void);
-bool perf_can_aux_sample(void);
 void perf_evlist__config(struct evlist *evlist, struct record_opts *opts,
                         struct callchain_param *callchain);
 int record_opts__config(struct record_opts *opts);
index 4be7634..30e1ee6 100644 (file)
@@ -33,6 +33,7 @@
 #include "tsc.h"
 #include "intel-pt.h"
 #include "config.h"
+#include "util/perf_api_probe.h"
 #include "util/synthetic-events.h"
 #include "time-utils.h"
 
diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_probe.c
new file mode 100644 (file)
index 0000000..1337965
--- /dev/null
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include "perf-sys.h"
+#include "util/cloexec.h"
+#include "util/evlist.h"
+#include "util/evsel.h"
+#include "util/parse-events.h"
+#include "util/perf_api_probe.h"
+#include <perf/cpumap.h>
+#include <errno.h>
+
+typedef void (*setup_probe_fn_t)(struct evsel *evsel);
+
+static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
+{
+       struct evlist *evlist;
+       struct evsel *evsel;
+       unsigned long flags = perf_event_open_cloexec_flag();
+       int err = -EAGAIN, fd;
+       static pid_t pid = -1;
+
+       evlist = evlist__new();
+       if (!evlist)
+               return -ENOMEM;
+
+       if (parse_events(evlist, str, NULL))
+               goto out_delete;
+
+       evsel = evlist__first(evlist);
+
+       while (1) {
+               fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
+               if (fd < 0) {
+                       if (pid == -1 && errno == EACCES) {
+                               pid = 0;
+                               continue;
+                       }
+                       goto out_delete;
+               }
+               break;
+       }
+       close(fd);
+
+       fn(evsel);
+
+       fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
+       if (fd < 0) {
+               if (errno == EINVAL)
+                       err = -EINVAL;
+               goto out_delete;
+       }
+       close(fd);
+       err = 0;
+
+out_delete:
+       evlist__delete(evlist);
+       return err;
+}
+
+static bool perf_probe_api(setup_probe_fn_t fn)
+{
+       const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
+       struct perf_cpu_map *cpus;
+       int cpu, ret, i = 0;
+
+       cpus = perf_cpu_map__new(NULL);
+       if (!cpus)
+               return false;
+       cpu = cpus->map[0];
+       perf_cpu_map__put(cpus);
+
+       do {
+               ret = perf_do_probe_api(fn, cpu, try[i++]);
+               if (!ret)
+                       return true;
+       } while (ret == -EAGAIN && try[i]);
+
+       return false;
+}
+
+static void perf_probe_sample_identifier(struct evsel *evsel)
+{
+       evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
+}
+
+static void perf_probe_comm_exec(struct evsel *evsel)
+{
+       evsel->core.attr.comm_exec = 1;
+}
+
+static void perf_probe_context_switch(struct evsel *evsel)
+{
+       evsel->core.attr.context_switch = 1;
+}
+
+bool perf_can_sample_identifier(void)
+{
+       return perf_probe_api(perf_probe_sample_identifier);
+}
+
+bool perf_can_comm_exec(void)
+{
+       return perf_probe_api(perf_probe_comm_exec);
+}
+
+bool perf_can_record_switch_events(void)
+{
+       return perf_probe_api(perf_probe_context_switch);
+}
+
+bool perf_can_record_cpu_wide(void)
+{
+       struct perf_event_attr attr = {
+               .type = PERF_TYPE_SOFTWARE,
+               .config = PERF_COUNT_SW_CPU_CLOCK,
+               .exclude_kernel = 1,
+       };
+       struct perf_cpu_map *cpus;
+       int cpu, fd;
+
+       cpus = perf_cpu_map__new(NULL);
+       if (!cpus)
+               return false;
+       cpu = cpus->map[0];
+       perf_cpu_map__put(cpus);
+
+       fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
+       if (fd < 0)
+               return false;
+       close(fd);
+
+       return true;
+}
+
+/*
+ * Architectures are expected to know if AUX area sampling is supported by the
+ * hardware. Here we check for kernel support.
+ */
+bool perf_can_aux_sample(void)
+{
+       struct perf_event_attr attr = {
+               .size = sizeof(struct perf_event_attr),
+               .exclude_kernel = 1,
+               /*
+                * Non-zero value causes the kernel to calculate the effective
+                * attribute size up to that byte.
+                */
+               .aux_sample_size = 1,
+       };
+       int fd;
+
+       fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
+       /*
+        * If the kernel attribute is big enough to contain aux_sample_size
+        * then we assume that it is supported. We are relying on the kernel to
+        * validate the attribute size before anything else that could be wrong.
+        */
+       if (fd < 0 && errno == E2BIG)
+               return false;
+       if (fd >= 0)
+               close(fd);
+
+       return true;
+}
diff --git a/tools/perf/util/perf_api_probe.h b/tools/perf/util/perf_api_probe.h
new file mode 100644 (file)
index 0000000..706c3c6
--- /dev/null
@@ -0,0 +1,14 @@
+
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_API_PROBE_H
+#define __PERF_API_PROBE_H
+
+#include <stdbool.h>
+
+bool perf_can_aux_sample(void);
+bool perf_can_comm_exec(void);
+bool perf_can_record_cpu_wide(void);
+bool perf_can_record_switch_events(void);
+bool perf_can_sample_identifier(void);
+
+#endif // __PERF_API_PROBE_H
index 6d3e3df..c2c8cce 100644 (file)
 #include <subcmd/parse-options.h>
 #include <perf/cpumap.h>
 #include "cloexec.h"
+#include "util/perf_api_probe.h"
 #include "record.h"
 #include "../perf-sys.h"
 
-typedef void (*setup_probe_fn_t)(struct evsel *evsel);
-
-static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
-{
-       struct evlist *evlist;
-       struct evsel *evsel;
-       unsigned long flags = perf_event_open_cloexec_flag();
-       int err = -EAGAIN, fd;
-       static pid_t pid = -1;
-
-       evlist = evlist__new();
-       if (!evlist)
-               return -ENOMEM;
-
-       if (parse_events(evlist, str, NULL))
-               goto out_delete;
-
-       evsel = evlist__first(evlist);
-
-       while (1) {
-               fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
-               if (fd < 0) {
-                       if (pid == -1 && errno == EACCES) {
-                               pid = 0;
-                               continue;
-                       }
-                       goto out_delete;
-               }
-               break;
-       }
-       close(fd);
-
-       fn(evsel);
-
-       fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
-       if (fd < 0) {
-               if (errno == EINVAL)
-                       err = -EINVAL;
-               goto out_delete;
-       }
-       close(fd);
-       err = 0;
-
-out_delete:
-       evlist__delete(evlist);
-       return err;
-}
-
-static bool perf_probe_api(setup_probe_fn_t fn)
-{
-       const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
-       struct perf_cpu_map *cpus;
-       int cpu, ret, i = 0;
-
-       cpus = perf_cpu_map__new(NULL);
-       if (!cpus)
-               return false;
-       cpu = cpus->map[0];
-       perf_cpu_map__put(cpus);
-
-       do {
-               ret = perf_do_probe_api(fn, cpu, try[i++]);
-               if (!ret)
-                       return true;
-       } while (ret == -EAGAIN && try[i]);
-
-       return false;
-}
-
-static void perf_probe_sample_identifier(struct evsel *evsel)
-{
-       evsel->core.attr.sample_type |= PERF_SAMPLE_IDENTIFIER;
-}
-
-static void perf_probe_comm_exec(struct evsel *evsel)
-{
-       evsel->core.attr.comm_exec = 1;
-}
-
-static void perf_probe_context_switch(struct evsel *evsel)
-{
-       evsel->core.attr.context_switch = 1;
-}
-
-bool perf_can_sample_identifier(void)
-{
-       return perf_probe_api(perf_probe_sample_identifier);
-}
-
-static bool perf_can_comm_exec(void)
-{
-       return perf_probe_api(perf_probe_comm_exec);
-}
-
-bool perf_can_record_switch_events(void)
-{
-       return perf_probe_api(perf_probe_context_switch);
-}
-
-bool perf_can_record_cpu_wide(void)
-{
-       struct perf_event_attr attr = {
-               .type = PERF_TYPE_SOFTWARE,
-               .config = PERF_COUNT_SW_CPU_CLOCK,
-               .exclude_kernel = 1,
-       };
-       struct perf_cpu_map *cpus;
-       int cpu, fd;
-
-       cpus = perf_cpu_map__new(NULL);
-       if (!cpus)
-               return false;
-       cpu = cpus->map[0];
-       perf_cpu_map__put(cpus);
-
-       fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
-       if (fd < 0)
-               return false;
-       close(fd);
-
-       return true;
-}
-
-/*
- * Architectures are expected to know if AUX area sampling is supported by the
- * hardware. Here we check for kernel support.
- */
-bool perf_can_aux_sample(void)
-{
-       struct perf_event_attr attr = {
-               .size = sizeof(struct perf_event_attr),
-               .exclude_kernel = 1,
-               /*
-                * Non-zero value causes the kernel to calculate the effective
-                * attribute size up to that byte.
-                */
-               .aux_sample_size = 1,
-       };
-       int fd;
-
-       fd = sys_perf_event_open(&attr, -1, 0, -1, 0);
-       /*
-        * If the kernel attribute is big enough to contain aux_sample_size
-        * then we assume that it is supported. We are relying on the kernel to
-        * validate the attribute size before anything else that could be wrong.
-        */
-       if (fd < 0 && errno == E2BIG)
-               return false;
-       if (fd >= 0)
-               close(fd);
-
-       return true;
-}
-
 /*
  * perf_evsel__config_leader_sampling() uses special rules for leader sampling.
  * However, if the leader is an AUX area event, then assume the event to sample