diff options
author | Andrei Vagin <avagin@gmail.com> | 2019-11-12 01:27:22 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-01-14 12:21:02 +0100 |
commit | 1854b97e4fa6a476d5cdc3dc30c42e1528699f87 (patch) | |
tree | f59aa3b14bd04c039b5921de0a7fdbb56d690663 /tools | |
parent | d5b0117ddd4949e9ed882b6ef91316719826e8a8 (diff) |
selftests/timens: Add a simple perf test for clock_gettime()
Output on success:
1..4
ok 1 host: clock: monotonic cycles: 148323947
ok 2 host: clock: boottime cycles: 148577503
ok 3 ns: clock: monotonic cycles: 137659217
ok 4 ns: clock: boottime cycles: 137959154
# Pass 4 Fail 0 Xfail 0 Xpass 0 Skip 0 Error 0
Output with lack of permissions:
1..4
ok 1 host: clock: monotonic cycles: 145671139
ok 2 host: clock: boottime cycles: 146958357
not ok 3 # SKIP need to run as root
Output without support of time namespaces:
1..4
ok 1 host: clock: monotonic cycles: 145671139
ok 2 host: clock: boottime cycles: 146958357
not ok 3 # SKIP Time namespaces are not supported
Co-developed-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-34-dima@arista.com
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/timens/.gitignore | 2 | ||||
-rw-r--r-- | tools/testing/selftests/timens/Makefile | 3 | ||||
-rw-r--r-- | tools/testing/selftests/timens/gettime_perf.c | 95 |
3 files changed, 99 insertions, 1 deletions
diff --git a/tools/testing/selftests/timens/.gitignore b/tools/testing/selftests/timens/.gitignore index 3b7eda8f35ce..16292e4d08a5 100644 --- a/tools/testing/selftests/timens/.gitignore +++ b/tools/testing/selftests/timens/.gitignore @@ -1,4 +1,6 @@ clock_nanosleep +gettime_perf +gettime_perf_cold procfs timens timer diff --git a/tools/testing/selftests/timens/Makefile b/tools/testing/selftests/timens/Makefile index 08164548a49d..6aefcaccb8f4 100644 --- a/tools/testing/selftests/timens/Makefile +++ b/tools/testing/selftests/timens/Makefile @@ -1,6 +1,7 @@ TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs +TEST_GEN_PROGS_EXTENDED := gettime_perf CFLAGS := -Wall -Werror -pthread -LDFLAGS := -lrt +LDFLAGS := -lrt -ldl include ../lib.mk diff --git a/tools/testing/selftests/timens/gettime_perf.c b/tools/testing/selftests/timens/gettime_perf.c new file mode 100644 index 000000000000..7bf841a3967b --- /dev/null +++ b/tools/testing/selftests/timens/gettime_perf.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <sched.h> +#include <time.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <dlfcn.h> + +#include "log.h" +#include "timens.h" + +typedef int (*vgettime_t)(clockid_t, struct timespec *); + +vgettime_t vdso_clock_gettime; + +static void fill_function_pointers(void) +{ + void *vdso = dlopen("linux-vdso.so.1", + RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); + if (!vdso) + vdso = dlopen("linux-gate.so.1", + RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); + if (!vdso) { + pr_err("[WARN]\tfailed to find vDSO\n"); + return; + } + + vdso_clock_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime"); + if (!vdso_clock_gettime) + pr_err("Warning: failed to find clock_gettime in vDSO\n"); + +} + +static void test(clock_t clockid, char *clockstr, bool in_ns) +{ + struct timespec tp, start; + long i = 0; + const int timeout = 3; + + vdso_clock_gettime(clockid, &start); + tp = start; + for (tp = start; start.tv_sec + timeout > tp.tv_sec || + (start.tv_sec + timeout == tp.tv_sec && + start.tv_nsec > tp.tv_nsec); i++) { + vdso_clock_gettime(clockid, &tp); + } + + ksft_test_result_pass("%s:\tclock: %10s\tcycles:\t%10ld\n", + in_ns ? "ns" : "host", clockstr, i); +} + +int main(int argc, char *argv[]) +{ + time_t offset = 10; + int nsfd; + + ksft_set_plan(8); + + fill_function_pointers(); + + test(CLOCK_MONOTONIC, "monotonic", false); + test(CLOCK_MONOTONIC_COARSE, "monotonic-coarse", false); + test(CLOCK_MONOTONIC_RAW, "monotonic-raw", false); + test(CLOCK_BOOTTIME, "boottime", false); + + nscheck(); + + if (unshare_timens()) + return 1; + + nsfd = open("/proc/self/ns/time_for_children", O_RDONLY); + if (nsfd < 0) + return pr_perror("Can't open a time namespace"); + + if (_settime(CLOCK_MONOTONIC, offset)) + return 1; + if (_settime(CLOCK_BOOTTIME, offset)) + return 1; + + if (setns(nsfd, CLONE_NEWTIME)) + return pr_perror("setns"); + + test(CLOCK_MONOTONIC, "monotonic", true); + test(CLOCK_MONOTONIC_COARSE, "monotonic-coarse", true); + test(CLOCK_MONOTONIC_RAW, "monotonic-raw", true); + test(CLOCK_BOOTTIME, "boottime", true); + + ksft_exit_pass(); + return 0; +} |