Skip to content

Commit 1854b97

Browse files
avaginKAGA-KOKO
authored andcommitted
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
1 parent d5b0117 commit 1854b97

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

tools/testing/selftests/timens/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
clock_nanosleep
2+
gettime_perf
3+
gettime_perf_cold
24
procfs
35
timens
46
timer
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs
2+
TEST_GEN_PROGS_EXTENDED := gettime_perf
23

34
CFLAGS := -Wall -Werror -pthread
4-
LDFLAGS := -lrt
5+
LDFLAGS := -lrt -ldl
56

67
include ../lib.mk
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#define _GNU_SOURCE
3+
#include <sys/types.h>
4+
#include <sys/stat.h>
5+
#include <errno.h>
6+
#include <fcntl.h>
7+
#include <sched.h>
8+
#include <time.h>
9+
#include <stdio.h>
10+
#include <unistd.h>
11+
#include <sys/syscall.h>
12+
#include <dlfcn.h>
13+
14+
#include "log.h"
15+
#include "timens.h"
16+
17+
typedef int (*vgettime_t)(clockid_t, struct timespec *);
18+
19+
vgettime_t vdso_clock_gettime;
20+
21+
static void fill_function_pointers(void)
22+
{
23+
void *vdso = dlopen("linux-vdso.so.1",
24+
RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
25+
if (!vdso)
26+
vdso = dlopen("linux-gate.so.1",
27+
RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
28+
if (!vdso) {
29+
pr_err("[WARN]\tfailed to find vDSO\n");
30+
return;
31+
}
32+
33+
vdso_clock_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime");
34+
if (!vdso_clock_gettime)
35+
pr_err("Warning: failed to find clock_gettime in vDSO\n");
36+
37+
}
38+
39+
static void test(clock_t clockid, char *clockstr, bool in_ns)
40+
{
41+
struct timespec tp, start;
42+
long i = 0;
43+
const int timeout = 3;
44+
45+
vdso_clock_gettime(clockid, &start);
46+
tp = start;
47+
for (tp = start; start.tv_sec + timeout > tp.tv_sec ||
48+
(start.tv_sec + timeout == tp.tv_sec &&
49+
start.tv_nsec > tp.tv_nsec); i++) {
50+
vdso_clock_gettime(clockid, &tp);
51+
}
52+
53+
ksft_test_result_pass("%s:\tclock: %10s\tcycles:\t%10ld\n",
54+
in_ns ? "ns" : "host", clockstr, i);
55+
}
56+
57+
int main(int argc, char *argv[])
58+
{
59+
time_t offset = 10;
60+
int nsfd;
61+
62+
ksft_set_plan(8);
63+
64+
fill_function_pointers();
65+
66+
test(CLOCK_MONOTONIC, "monotonic", false);
67+
test(CLOCK_MONOTONIC_COARSE, "monotonic-coarse", false);
68+
test(CLOCK_MONOTONIC_RAW, "monotonic-raw", false);
69+
test(CLOCK_BOOTTIME, "boottime", false);
70+
71+
nscheck();
72+
73+
if (unshare_timens())
74+
return 1;
75+
76+
nsfd = open("/proc/self/ns/time_for_children", O_RDONLY);
77+
if (nsfd < 0)
78+
return pr_perror("Can't open a time namespace");
79+
80+
if (_settime(CLOCK_MONOTONIC, offset))
81+
return 1;
82+
if (_settime(CLOCK_BOOTTIME, offset))
83+
return 1;
84+
85+
if (setns(nsfd, CLONE_NEWTIME))
86+
return pr_perror("setns");
87+
88+
test(CLOCK_MONOTONIC, "monotonic", true);
89+
test(CLOCK_MONOTONIC_COARSE, "monotonic-coarse", true);
90+
test(CLOCK_MONOTONIC_RAW, "monotonic-raw", true);
91+
test(CLOCK_BOOTTIME, "boottime", true);
92+
93+
ksft_exit_pass();
94+
return 0;
95+
}

0 commit comments

Comments
 (0)