From: Andrei Vagin <avagin@google.com>
To: Kees Cook <keescook@chromium.org>, Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org,
Christian Brauner <brauner@kernel.org>,
Chen Yu <yu.c.chen@intel.com>,
avagin@gmail.com, Andrei Vagin <avagin@google.com>,
Andy Lutomirski <luto@amacapital.net>,
Dietmar Eggemann <dietmar.eggemann@arm.com>,
Ingo Molnar <mingo@redhat.com>,
Juri Lelli <juri.lelli@redhat.com>,
Peter Oskolkov <posk@google.com>,
Tycho Andersen <tycho@tycho.pizza>,
Will Drewry <wad@chromium.org>,
Vincent Guittot <vincent.guittot@linaro.org>
Subject: [PATCH 6/6] perf/benchmark: add a new benchmark for seccom_unotify
Date: Tue, 7 Mar 2023 23:32:01 -0800 [thread overview]
Message-ID: <20230308073201.3102738-7-avagin@google.com> (raw)
In-Reply-To: <20230308073201.3102738-1-avagin@google.com>
The benchmark is similar to the pipe benchmark. It creates two processes,
one is calling syscalls, and another process is handling them via seccomp
user notifications. It measures the time required to run a specified number
of interations.
$ ./perf bench sched seccomp-notify --sync-mode --loop 1000000
# Running 'sched/seccomp-notify' benchmark:
# Executed 1000000 system calls
Total time: 2.769 [sec]
2.769629 usecs/op
361059 ops/sec
$ ./perf bench sched seccomp-notify
# Running 'sched/seccomp-notify' benchmark:
# Executed 1000000 system calls
Total time: 8.571 [sec]
8.571119 usecs/op
116670 ops/sec
Signed-off-by: Andrei Vagin <avagin@google.com>
---
tools/arch/x86/include/uapi/asm/unistd_32.h | 3 +
tools/arch/x86/include/uapi/asm/unistd_64.h | 3 +
tools/perf/bench/Build | 1 +
tools/perf/bench/bench.h | 1 +
tools/perf/bench/sched-seccomp-notify.c | 168 ++++++++++++++++++++
tools/perf/builtin-bench.c | 1 +
6 files changed, 177 insertions(+)
create mode 100644 tools/perf/bench/sched-seccomp-notify.c
diff --git a/tools/arch/x86/include/uapi/asm/unistd_32.h b/tools/arch/x86/include/uapi/asm/unistd_32.h
index 2712d5e03e2e..5fb3589c14bf 100644
--- a/tools/arch/x86/include/uapi/asm/unistd_32.h
+++ b/tools/arch/x86/include/uapi/asm/unistd_32.h
@@ -23,3 +23,6 @@
#ifndef __NR_setns
#define __NR_setns 346
#endif
+#ifdef __NR_seccomp
+#define __NR_seccomp 354
+#endif
diff --git a/tools/arch/x86/include/uapi/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
index a6f7fe84d4df..e0549617f9d7 100644
--- a/tools/arch/x86/include/uapi/asm/unistd_64.h
+++ b/tools/arch/x86/include/uapi/asm/unistd_64.h
@@ -23,3 +23,6 @@
#ifndef __NR_getcpu
#define __NR_getcpu 309
#endif
+#ifndef __NR_seccomp
+#define __NR_seccomp 317
+#endif
diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index 6b6155a8ad09..e3ec2c1b0682 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -1,5 +1,6 @@
perf-y += sched-messaging.o
perf-y += sched-pipe.o
+perf-y += sched-seccomp-notify.o
perf-y += syscall.o
perf-y += mem-functions.o
perf-y += futex-hash.o
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index e43893151a3e..9d28510fcf9d 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -21,6 +21,7 @@ extern struct timeval bench__start, bench__end, bench__runtime;
int bench_numa(int argc, const char **argv);
int bench_sched_messaging(int argc, const char **argv);
int bench_sched_pipe(int argc, const char **argv);
+int bench_sched_seccomp_notify(int argc, const char **argv);
int bench_syscall_basic(int argc, const char **argv);
int bench_syscall_getpgid(int argc, const char **argv);
int bench_syscall_execve(int argc, const char **argv);
diff --git a/tools/perf/bench/sched-seccomp-notify.c b/tools/perf/bench/sched-seccomp-notify.c
new file mode 100644
index 000000000000..443f4b43702d
--- /dev/null
+++ b/tools/perf/bench/sched-seccomp-notify.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <subcmd/parse-options.h>
+#include "bench.h"
+
+#include <uapi/linux/filter.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <linux/unistd.h>
+#include <sys/syscall.h>
+#include <sys/ioctl.h>
+#include <linux/time64.h>
+#include <linux/seccomp.h>
+#include <sys/prctl.h>
+
+#include <unistd.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#define LOOPS_DEFAULT 1000000UL
+static uint64_t loops = LOOPS_DEFAULT;
+static bool sync_mode;
+
+static const struct option options[] = {
+ OPT_U64('l', "loop", &loops, "Specify number of loops"),
+ OPT_BOOLEAN('s', "sync-mode", &sync_mode,
+ "Enable the synchronious mode for seccomp notifications"),
+ OPT_END()
+};
+
+static const char * const bench_seccomp_usage[] = {
+ "perf bench sched secccomp-notify <options>",
+ NULL
+};
+
+static int seccomp(unsigned int op, unsigned int flags, void *args)
+{
+ return syscall(__NR_seccomp, op, flags, args);
+}
+
+static int user_notif_syscall(int nr, unsigned int flags)
+{
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ offsetof(struct seccomp_data, nr)),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, nr, 0, 1),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_USER_NOTIF),
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ };
+
+ struct sock_fprog prog = {
+ .len = (unsigned short)ARRAY_SIZE(filter),
+ .filter = filter,
+ };
+
+ return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog);
+}
+
+#define USER_NOTIF_MAGIC INT_MAX
+static void user_notification_sync_loop(int listener)
+{
+ struct seccomp_notif_resp resp;
+ struct seccomp_notif req;
+ uint64_t nr;
+
+ for (nr = 0; nr < loops; nr++) {
+ memset(&req, 0, sizeof(req));
+ assert(ioctl(listener, SECCOMP_IOCTL_NOTIF_RECV, &req) == 0);
+
+ assert(req.data.nr == __NR_gettid);
+
+ resp.id = req.id;
+ resp.error = 0;
+ resp.val = USER_NOTIF_MAGIC;
+ resp.flags = 0;
+ assert(ioctl(listener, SECCOMP_IOCTL_NOTIF_SEND, &resp) == 0);
+ }
+}
+
+#ifndef SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP
+#define SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP (1UL << 0)
+#define SECCOMP_IOCTL_NOTIF_SET_FLAGS SECCOMP_IOW(4, __u64)
+#endif
+int bench_sched_seccomp_notify(int argc, const char **argv)
+{
+ struct timeval start, stop, diff;
+ unsigned long long result_usec = 0;
+ int status, listener;
+ pid_t pid;
+ long ret;
+
+ argc = parse_options(argc, argv, options, bench_seccomp_usage, 0);
+
+ gettimeofday(&start, NULL);
+
+ prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ listener = user_notif_syscall(__NR_gettid,
+ SECCOMP_FILTER_FLAG_NEW_LISTENER);
+ assert(listener >= 0);
+
+ pid = fork();
+ assert(pid >= 0);
+ if (pid == 0) {
+ assert(prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) == 0);
+ while (1) {
+ ret = syscall(__NR_gettid);
+ if (ret == USER_NOTIF_MAGIC)
+ continue;
+ break;
+ }
+ _exit(1);
+ }
+
+ if (sync_mode) {
+ assert(ioctl(listener, SECCOMP_IOCTL_NOTIF_SET_FLAGS,
+ SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP, 0) == 0);
+ }
+ user_notification_sync_loop(listener);
+
+ kill(pid, SIGKILL);
+ assert(waitpid(pid, &status, 0) == pid);
+ assert(WIFSIGNALED(status));
+ assert(WTERMSIG(status) == SIGKILL);
+
+ gettimeofday(&stop, NULL);
+ timersub(&stop, &start, &diff);
+
+ switch (bench_format) {
+ case BENCH_FORMAT_DEFAULT:
+ printf("# Executed %lu system calls\n\n",
+ loops);
+
+ result_usec = diff.tv_sec * USEC_PER_SEC;
+ result_usec += diff.tv_usec;
+
+ printf(" %14s: %lu.%03lu [sec]\n\n", "Total time",
+ (unsigned long) diff.tv_sec,
+ (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
+
+ printf(" %14lf usecs/op\n",
+ (double)result_usec / (double)loops);
+ printf(" %14d ops/sec\n",
+ (int)((double)loops /
+ ((double)result_usec / (double)USEC_PER_SEC)));
+ break;
+
+ case BENCH_FORMAT_SIMPLE:
+ printf("%lu.%03lu\n",
+ (unsigned long) diff.tv_sec,
+ (unsigned long) (diff.tv_usec / USEC_PER_MSEC));
+ break;
+
+ default:
+ /* reaching here is something disaster */
+ fprintf(stderr, "Unknown format:%d\n", bench_format);
+ exit(1);
+ break;
+ }
+
+ return 0;
+}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 814e9afc86f6..db57813fe4e5 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -46,6 +46,7 @@ static struct bench numa_benchmarks[] = {
static struct bench sched_benchmarks[] = {
{ "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging },
{ "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe },
+ { "seccomp-notify", "Benchmark for seccomp user notify", bench_sched_seccomp_notify},
{ "all", "Run all scheduler benchmarks", NULL },
{ NULL, NULL, NULL }
};
--
2.40.0.rc0.216.gc4246ad0f0-goog
next prev parent reply other threads:[~2023-03-08 7:32 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-08 7:31 [PATCH 0/6 v5 RESEND] seccomp: add the synchronous mode for seccomp_unotify Andrei Vagin
2023-03-08 7:31 ` [PATCH 1/6] seccomp: don't use semaphore and wait_queue together Andrei Vagin
2023-03-08 7:31 ` [PATCH 2/6] sched: add WF_CURRENT_CPU and externise ttwu Andrei Vagin
2023-04-08 3:20 ` Chen Yu
2023-04-10 4:56 ` Andrei Vagin
2023-04-10 17:27 ` Andy Lutomirski
2023-04-12 19:38 ` Andrei Vagin
2023-04-10 18:16 ` Chen Yu
2023-04-11 1:50 ` Chen Yu
2023-04-17 19:24 ` Andrei Vagin
2023-03-08 7:31 ` [PATCH 3/6] sched: add a few helpers to wake up tasks on the current cpu Andrei Vagin
2023-04-26 14:43 ` Bernd Schubert
2023-04-26 18:52 ` Andrei Vagin
2023-04-26 19:35 ` Bernd Schubert
2023-04-26 20:57 ` Bernd Schubert
2023-03-08 7:31 ` [PATCH 4/6] seccomp: add the synchronous mode for seccomp_unotify Andrei Vagin
2023-04-06 3:42 ` Andy Lutomirski
2023-04-10 6:59 ` Andrei Vagin
2023-04-10 20:53 ` Andy Lutomirski
2023-03-08 7:32 ` [PATCH 5/6] selftest/seccomp: add a new test for the sync mode of seccomp_user_notify Andrei Vagin
2023-03-08 7:32 ` Andrei Vagin [this message]
2023-09-08 17:35 ` [PATCH] perf/benchmark: Fix ifdef in header file uapi/asm/unistd_32.h Vijayendra Suman
2023-09-08 17:38 ` Andrei Vagin
2023-09-08 18:18 ` Tycho Andersen
2023-10-17 8:24 ` [PATCH 6/6] perf/benchmark: add a new benchmark for seccom_unotify Jiri Slaby
2023-03-21 18:19 ` [PATCH 0/6 v5 RESEND] seccomp: add the synchronous mode for seccomp_unotify Andrei Vagin
2023-03-27 10:27 ` Peter Zijlstra
2023-04-03 18:32 ` Andrei Vagin
2023-04-06 3:19 ` Kees Cook
2023-06-28 18:44 ` Andrei Vagin
2023-06-28 23:32 ` Kees Cook
-- strict thread matches above, loose matches on Subject: below --
2023-02-02 3:04 [PATCH 0/6 v5] " Andrei Vagin
2023-02-02 3:04 ` [PATCH 6/6] perf/benchmark: add a new benchmark for seccom_unotify Andrei Vagin
2023-01-24 23:41 [PATCH 0/6 v4] seccomp: add the synchronous mode for seccomp_unotify Andrei Vagin
2023-01-24 23:41 ` [PATCH 6/6] perf/benchmark: add a new benchmark for seccom_unotify Andrei Vagin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230308073201.3102738-7-avagin@google.com \
--to=avagin@google.com \
--cc=avagin@gmail.com \
--cc=brauner@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=posk@google.com \
--cc=tycho@tycho.pizza \
--cc=vincent.guittot@linaro.org \
--cc=wad@chromium.org \
--cc=yu.c.chen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome