2 * Strictly speaking, this is not a test. But it can report during test
3 * runs so relative performace can be measured.
11 #include <linux/filter.h>
12 #include <linux/seccomp.h>
13 #include <sys/prctl.h>
14 #include <sys/syscall.h>
15 #include <sys/types.h>
17 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
19 unsigned long long timing(clockid_t clk_id
, unsigned long long samples
)
23 struct timespec start
, finish
;
26 assert(clock_gettime(clk_id
, &start
) == 0);
27 for (i
= 0; i
< samples
; i
++) {
28 ret
= syscall(__NR_getpid
);
31 assert(clock_gettime(clk_id
, &finish
) == 0);
33 i
= finish
.tv_sec
- start
.tv_sec
;
35 i
+= finish
.tv_nsec
- start
.tv_nsec
;
37 printf("%lu.%09lu - %lu.%09lu = %llu\n",
38 finish
.tv_sec
, finish
.tv_nsec
,
39 start
.tv_sec
, start
.tv_nsec
,
45 unsigned long long calibrate(void)
49 printf("Calibrating reasonable sample size...\n");
52 unsigned long long samples
= 1 << i
;
54 /* Find something that takes more than 5 seconds to run. */
55 if (timing(CLOCK_REALTIME
, samples
) / 1000000000ULL > 5)
60 int main(int argc
, char *argv
[])
62 struct sock_filter filter
[] = {
63 BPF_STMT(BPF_RET
|BPF_K
, SECCOMP_RET_ALLOW
),
65 struct sock_fprog prog
= {
66 .len
= (unsigned short)ARRAY_SIZE(filter
),
70 unsigned long long samples
;
71 unsigned long long native
, filtered
;
74 samples
= strtoull(argv
[1], NULL
, 0);
76 samples
= calibrate();
78 printf("Benchmarking %llu samples...\n", samples
);
80 native
= timing(CLOCK_PROCESS_CPUTIME_ID
, samples
) / samples
;
81 printf("getpid native: %llu ns\n", native
);
83 ret
= prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0);
86 ret
= prctl(PR_SET_SECCOMP
, SECCOMP_MODE_FILTER
, &prog
);
89 filtered
= timing(CLOCK_PROCESS_CPUTIME_ID
, samples
) / samples
;
90 printf("getpid RET_ALLOW: %llu ns\n", filtered
);
92 printf("Estimated seccomp overhead per syscall: %llu ns\n",
95 if (filtered
== native
)
96 printf("Trying running again with more samples.\n");