]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
perf tests tsc: Make tsc testing as a common testing
authorLeo Yan <leo.yan@linaro.org>
Mon, 19 Oct 2020 10:02:35 +0000 (18:02 +0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 4 Nov 2020 12:42:40 +0000 (09:42 -0300)
x86 arch provides the testing for conversion between tsc and perf time,
the testing is located in x86 arch folder.  Move this testing out from
x86 arch folder and place it into the common testing folder, so allows
to execute tsc testing on other architectures (e.g. Arm64).

This patch removes the inclusion of "arch-tests.h" from the testing
code, this can avoid building failure if any arch has no this header
file.

Committer testing:

  $ perf test -v tsc
  Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc
  70: Convert perf time to TSC                                        :
  --- start ---
  test child forked, pid 4032834
  mmap size 528384B
  1st event perf time 165409788843605 tsc 336578703793868
  rdtsc          time 165409788854986 tsc 336578703837038
  2nd event perf time 165409788855487 tsc 336578703838935
  test child finished with 0
  ---- end ----
  Convert perf time to TSC: Ok
  $

Signed-off-by: Leo Yan <leo.yan@linaro.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20201019100236.23675-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/x86/include/arch-tests.h
tools/perf/arch/x86/tests/Build
tools/perf/arch/x86/tests/arch-tests.c
tools/perf/arch/x86/tests/perf-time-to-tsc.c [deleted file]
tools/perf/tests/Build
tools/perf/tests/builtin-test.c
tools/perf/tests/perf-time-to-tsc.c [new file with mode: 0644]
tools/perf/tests/tests.h

index c41c5affe4be7744c4404b273b0853348cfc69fa..6a54b94f1c25b4c2798861e9662e0c957b4d5ce9 100644 (file)
@@ -7,7 +7,6 @@ struct test;
 
 /* Tests */
 int test__rdpmc(struct test *test __maybe_unused, int subtest);
-int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest);
 int test__insn_x86(struct test *test __maybe_unused, int subtest);
 int test__intel_pt_pkt_decoder(struct test *test, int subtest);
 int test__bp_modify(struct test *test, int subtest);
index 2997c506550c1330fb2af4b0d42dd74137f0b42d..36d4f248b51dbceda1364767b6949fe720cd6770 100644 (file)
@@ -3,6 +3,5 @@ perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
 
 perf-y += arch-tests.o
 perf-y += rdpmc.o
-perf-y += perf-time-to-tsc.o
 perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-pkt-decoder-test.o
 perf-$(CONFIG_X86_64) += bp-modify.o
index 6763135aec17b2712199d3573d111bf364a9df50..bc25d727b4e9af4be2b2d360b928d9ab01fca7ae 100644 (file)
@@ -8,10 +8,6 @@ struct test arch_tests[] = {
                .desc = "x86 rdpmc",
                .func = test__rdpmc,
        },
-       {
-               .desc = "Convert perf time to TSC",
-               .func = test__perf_time_to_tsc,
-       },
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
        {
                .desc = "DWARF unwind",
diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
deleted file mode 100644 (file)
index 026d32e..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <linux/types.h>
-#include <sys/prctl.h>
-#include <perf/cpumap.h>
-#include <perf/evlist.h>
-#include <perf/mmap.h>
-
-#include "debug.h"
-#include "parse-events.h"
-#include "evlist.h"
-#include "evsel.h"
-#include "thread_map.h"
-#include "record.h"
-#include "tsc.h"
-#include "util/mmap.h"
-#include "tests/tests.h"
-
-#include "arch-tests.h"
-
-#define CHECK__(x) {                           \
-       while ((x) < 0) {                       \
-               pr_debug(#x " failed!\n");      \
-               goto out_err;                   \
-       }                                       \
-}
-
-#define CHECK_NOT_NULL__(x) {                  \
-       while ((x) == NULL) {                   \
-               pr_debug(#x " failed!\n");      \
-               goto out_err;                   \
-       }                                       \
-}
-
-/**
- * test__perf_time_to_tsc - test converting perf time to TSC.
- *
- * This function implements a test that checks that the conversion of perf time
- * to and from TSC is consistent with the order of events.  If the test passes
- * %0 is returned, otherwise %-1 is returned.  If TSC conversion is not
- * supported then then the test passes but " (not supported)" is printed.
- */
-int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused)
-{
-       struct record_opts opts = {
-               .mmap_pages          = UINT_MAX,
-               .user_freq           = UINT_MAX,
-               .user_interval       = ULLONG_MAX,
-               .target              = {
-                       .uses_mmap   = true,
-               },
-               .sample_time         = true,
-       };
-       struct perf_thread_map *threads = NULL;
-       struct perf_cpu_map *cpus = NULL;
-       struct evlist *evlist = NULL;
-       struct evsel *evsel = NULL;
-       int err = -1, ret, i;
-       const char *comm1, *comm2;
-       struct perf_tsc_conversion tc;
-       struct perf_event_mmap_page *pc;
-       union perf_event *event;
-       u64 test_tsc, comm1_tsc, comm2_tsc;
-       u64 test_time, comm1_time = 0, comm2_time = 0;
-       struct mmap *md;
-
-       threads = thread_map__new(-1, getpid(), UINT_MAX);
-       CHECK_NOT_NULL__(threads);
-
-       cpus = perf_cpu_map__new(NULL);
-       CHECK_NOT_NULL__(cpus);
-
-       evlist = evlist__new();
-       CHECK_NOT_NULL__(evlist);
-
-       perf_evlist__set_maps(&evlist->core, cpus, threads);
-
-       CHECK__(parse_events(evlist, "cycles:u", NULL));
-
-       perf_evlist__config(evlist, &opts, NULL);
-
-       evsel = evlist__first(evlist);
-
-       evsel->core.attr.comm = 1;
-       evsel->core.attr.disabled = 1;
-       evsel->core.attr.enable_on_exec = 0;
-
-       CHECK__(evlist__open(evlist));
-
-       CHECK__(evlist__mmap(evlist, UINT_MAX));
-
-       pc = evlist->mmap[0].core.base;
-       ret = perf_read_tsc_conversion(pc, &tc);
-       if (ret) {
-               if (ret == -EOPNOTSUPP) {
-                       fprintf(stderr, " (not supported)");
-                       return 0;
-               }
-               goto out_err;
-       }
-
-       evlist__enable(evlist);
-
-       comm1 = "Test COMM 1";
-       CHECK__(prctl(PR_SET_NAME, (unsigned long)comm1, 0, 0, 0));
-
-       test_tsc = rdtsc();
-
-       comm2 = "Test COMM 2";
-       CHECK__(prctl(PR_SET_NAME, (unsigned long)comm2, 0, 0, 0));
-
-       evlist__disable(evlist);
-
-       for (i = 0; i < evlist->core.nr_mmaps; i++) {
-               md = &evlist->mmap[i];
-               if (perf_mmap__read_init(&md->core) < 0)
-                       continue;
-
-               while ((event = perf_mmap__read_event(&md->core)) != NULL) {
-                       struct perf_sample sample;
-
-                       if (event->header.type != PERF_RECORD_COMM ||
-                           (pid_t)event->comm.pid != getpid() ||
-                           (pid_t)event->comm.tid != getpid())
-                               goto next_event;
-
-                       if (strcmp(event->comm.comm, comm1) == 0) {
-                               CHECK__(evsel__parse_sample(evsel, event, &sample));
-                               comm1_time = sample.time;
-                       }
-                       if (strcmp(event->comm.comm, comm2) == 0) {
-                               CHECK__(evsel__parse_sample(evsel, event, &sample));
-                               comm2_time = sample.time;
-                       }
-next_event:
-                       perf_mmap__consume(&md->core);
-               }
-               perf_mmap__read_done(&md->core);
-       }
-
-       if (!comm1_time || !comm2_time)
-               goto out_err;
-
-       test_time = tsc_to_perf_time(test_tsc, &tc);
-       comm1_tsc = perf_time_to_tsc(comm1_time, &tc);
-       comm2_tsc = perf_time_to_tsc(comm2_time, &tc);
-
-       pr_debug("1st event perf time %"PRIu64" tsc %"PRIu64"\n",
-                comm1_time, comm1_tsc);
-       pr_debug("rdtsc          time %"PRIu64" tsc %"PRIu64"\n",
-                test_time, test_tsc);
-       pr_debug("2nd event perf time %"PRIu64" tsc %"PRIu64"\n",
-                comm2_time, comm2_tsc);
-
-       if (test_time <= comm1_time ||
-           test_time >= comm2_time)
-               goto out_err;
-
-       if (test_tsc <= comm1_tsc ||
-           test_tsc >= comm2_tsc)
-               goto out_err;
-
-       err = 0;
-
-out_err:
-       evlist__delete(evlist);
-       return err;
-}
index 4d15bf6041fb9520961d5340114089f23f13bcd8..aa4dc4f5abde0b5c5be5724939fb2e47cf8fcef3 100644 (file)
@@ -62,6 +62,7 @@ perf-y += pfm.o
 perf-y += parse-metric.o
 perf-y += pe-file-parsing.o
 perf-y += expand-cgroup.o
+perf-y += perf-time-to-tsc.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
        $(call rule_mkdir)
index 132bdb3e6c31a0cb4e4d668b10445d992c92484b..02e7bbf70419aedd420056e0f519a12687b43e3e 100644 (file)
@@ -349,6 +349,10 @@ static struct test generic_tests[] = {
                .desc = "Event expansion for cgroups",
                .func = test__expand_cgroup_events,
        },
+       {
+               .desc = "Convert perf time to TSC",
+               .func = test__perf_time_to_tsc,
+       },
        {
                .func = NULL,
        },
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
new file mode 100644 (file)
index 0000000..aee97c1
--- /dev/null
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/types.h>
+#include <sys/prctl.h>
+#include <perf/cpumap.h>
+#include <perf/evlist.h>
+#include <perf/mmap.h>
+
+#include "debug.h"
+#include "parse-events.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "thread_map.h"
+#include "record.h"
+#include "tsc.h"
+#include "mmap.h"
+#include "tests.h"
+
+#define CHECK__(x) {                           \
+       while ((x) < 0) {                       \
+               pr_debug(#x " failed!\n");      \
+               goto out_err;                   \
+       }                                       \
+}
+
+#define CHECK_NOT_NULL__(x) {                  \
+       while ((x) == NULL) {                   \
+               pr_debug(#x " failed!\n");      \
+               goto out_err;                   \
+       }                                       \
+}
+
+/**
+ * test__perf_time_to_tsc - test converting perf time to TSC.
+ *
+ * This function implements a test that checks that the conversion of perf time
+ * to and from TSC is consistent with the order of events.  If the test passes
+ * %0 is returned, otherwise %-1 is returned.  If TSC conversion is not
+ * supported then then the test passes but " (not supported)" is printed.
+ */
+int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused)
+{
+       struct record_opts opts = {
+               .mmap_pages          = UINT_MAX,
+               .user_freq           = UINT_MAX,
+               .user_interval       = ULLONG_MAX,
+               .target              = {
+                       .uses_mmap   = true,
+               },
+               .sample_time         = true,
+       };
+       struct perf_thread_map *threads = NULL;
+       struct perf_cpu_map *cpus = NULL;
+       struct evlist *evlist = NULL;
+       struct evsel *evsel = NULL;
+       int err = -1, ret, i;
+       const char *comm1, *comm2;
+       struct perf_tsc_conversion tc;
+       struct perf_event_mmap_page *pc;
+       union perf_event *event;
+       u64 test_tsc, comm1_tsc, comm2_tsc;
+       u64 test_time, comm1_time = 0, comm2_time = 0;
+       struct mmap *md;
+
+       threads = thread_map__new(-1, getpid(), UINT_MAX);
+       CHECK_NOT_NULL__(threads);
+
+       cpus = perf_cpu_map__new(NULL);
+       CHECK_NOT_NULL__(cpus);
+
+       evlist = evlist__new();
+       CHECK_NOT_NULL__(evlist);
+
+       perf_evlist__set_maps(&evlist->core, cpus, threads);
+
+       CHECK__(parse_events(evlist, "cycles:u", NULL));
+
+       perf_evlist__config(evlist, &opts, NULL);
+
+       evsel = evlist__first(evlist);
+
+       evsel->core.attr.comm = 1;
+       evsel->core.attr.disabled = 1;
+       evsel->core.attr.enable_on_exec = 0;
+
+       CHECK__(evlist__open(evlist));
+
+       CHECK__(evlist__mmap(evlist, UINT_MAX));
+
+       pc = evlist->mmap[0].core.base;
+       ret = perf_read_tsc_conversion(pc, &tc);
+       if (ret) {
+               if (ret == -EOPNOTSUPP) {
+                       fprintf(stderr, " (not supported)");
+                       return 0;
+               }
+               goto out_err;
+       }
+
+       evlist__enable(evlist);
+
+       comm1 = "Test COMM 1";
+       CHECK__(prctl(PR_SET_NAME, (unsigned long)comm1, 0, 0, 0));
+
+       test_tsc = rdtsc();
+
+       comm2 = "Test COMM 2";
+       CHECK__(prctl(PR_SET_NAME, (unsigned long)comm2, 0, 0, 0));
+
+       evlist__disable(evlist);
+
+       for (i = 0; i < evlist->core.nr_mmaps; i++) {
+               md = &evlist->mmap[i];
+               if (perf_mmap__read_init(&md->core) < 0)
+                       continue;
+
+               while ((event = perf_mmap__read_event(&md->core)) != NULL) {
+                       struct perf_sample sample;
+
+                       if (event->header.type != PERF_RECORD_COMM ||
+                           (pid_t)event->comm.pid != getpid() ||
+                           (pid_t)event->comm.tid != getpid())
+                               goto next_event;
+
+                       if (strcmp(event->comm.comm, comm1) == 0) {
+                               CHECK__(evsel__parse_sample(evsel, event, &sample));
+                               comm1_time = sample.time;
+                       }
+                       if (strcmp(event->comm.comm, comm2) == 0) {
+                               CHECK__(evsel__parse_sample(evsel, event, &sample));
+                               comm2_time = sample.time;
+                       }
+next_event:
+                       perf_mmap__consume(&md->core);
+               }
+               perf_mmap__read_done(&md->core);
+       }
+
+       if (!comm1_time || !comm2_time)
+               goto out_err;
+
+       test_time = tsc_to_perf_time(test_tsc, &tc);
+       comm1_tsc = perf_time_to_tsc(comm1_time, &tc);
+       comm2_tsc = perf_time_to_tsc(comm2_time, &tc);
+
+       pr_debug("1st event perf time %"PRIu64" tsc %"PRIu64"\n",
+                comm1_time, comm1_tsc);
+       pr_debug("rdtsc          time %"PRIu64" tsc %"PRIu64"\n",
+                test_time, test_tsc);
+       pr_debug("2nd event perf time %"PRIu64" tsc %"PRIu64"\n",
+                comm2_time, comm2_tsc);
+
+       if (test_time <= comm1_time ||
+           test_time >= comm2_time)
+               goto out_err;
+
+       if (test_tsc <= comm1_tsc ||
+           test_tsc >= comm2_tsc)
+               goto out_err;
+
+       err = 0;
+
+out_err:
+       evlist__delete(evlist);
+       return err;
+}
index c85a2c08e40720f9da1c5f4ba4d2e95220db9bba..c9b180e640e5f21cd5c75e4a42d1f3d38bb206d6 100644 (file)
@@ -124,6 +124,7 @@ int test__pfm_subtest_get_nr(void);
 int test__parse_metric(struct test *test, int subtest);
 int test__pe_file_parsing(struct test *test, int subtest);
 int test__expand_cgroup_events(struct test *test, int subtest);
+int test__perf_time_to_tsc(struct test *test, int subtest);
 
 bool test__bp_signal_is_supported(void);
 bool test__bp_account_is_supported(void);