From 2526852fc5e011070aca849fad9eef8995e07267 Mon Sep 17 00:00:00 2001 From: Ryan Roberts Date: Wed, 30 Jul 2025 13:24:16 +0100 Subject: [PATCH 1/2] container: Rename micromm to microbench We have a number of small/drive-by benchmarks that are starting to collect, so let's rename the micromm container image to microbench, then we can add future non-mm benchmarks to it. Signed-off-by: Ryan Roberts --- benchmarks/micromm/base.yaml | 2 +- containers/{micromm => microbench}/Dockerfile | 0 containers/{micromm => microbench}/exec.py | 0 containers/{micromm => microbench}/micromm.c | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename containers/{micromm => microbench}/Dockerfile (100%) rename containers/{micromm => microbench}/exec.py (100%) rename containers/{micromm => microbench}/micromm.c (100%) diff --git a/benchmarks/micromm/base.yaml b/benchmarks/micromm/base.yaml index d844cc6..51ab6ae 100644 --- a/benchmarks/micromm/base.yaml +++ b/benchmarks/micromm/base.yaml @@ -1,2 +1,2 @@ suite: micromm -image: registry.gitlab.arm.com/tooling/fastpath/containers/micromm:v1.0 +image: registry.gitlab.arm.com/tooling/fastpath/containers/microbench:v1.0 diff --git a/containers/micromm/Dockerfile b/containers/microbench/Dockerfile similarity index 100% rename from containers/micromm/Dockerfile rename to containers/microbench/Dockerfile diff --git a/containers/micromm/exec.py b/containers/microbench/exec.py similarity index 100% rename from containers/micromm/exec.py rename to containers/microbench/exec.py diff --git a/containers/micromm/micromm.c b/containers/microbench/micromm.c similarity index 100% rename from containers/micromm/micromm.c rename to containers/microbench/micromm.c -- GitLab From a7a94ab59de86d3b360197e811bde65c65cd0a25 Mon Sep 17 00:00:00 2001 From: Ryan Roberts Date: Wed, 30 Jul 2025 13:26:39 +0100 Subject: [PATCH 2/2] benchmark: Add new syscall benchmark suite Add some simple benchmarks to test performance of syscall entry and exit logic. For now, we have 3 benchmarks, getpid, getppid and invalid. The first 2 call the respective syscalls, the 3rd one makes a syscall with an invalid syscall number. Benchmark yamls are added to the benchmark library: syscall/getpid.yaml syscall/getppid.yaml syscall/invalid.yaml Signed-off-by: Ryan Roberts --- benchmarks/syscall/base.yaml | 4 ++ benchmarks/syscall/getpid.yaml | 5 ++ benchmarks/syscall/getppid.yaml | 5 ++ benchmarks/syscall/invalid.yaml | 5 ++ containers/microbench/Dockerfile | 10 +++- containers/microbench/exec.py | 85 ++++++++++++++++++++++++-------- containers/microbench/syscall.c | 51 +++++++++++++++++++ 7 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 benchmarks/syscall/base.yaml create mode 100644 benchmarks/syscall/getpid.yaml create mode 100644 benchmarks/syscall/getppid.yaml create mode 100644 benchmarks/syscall/invalid.yaml create mode 100644 containers/microbench/syscall.c diff --git a/benchmarks/syscall/base.yaml b/benchmarks/syscall/base.yaml new file mode 100644 index 0000000..8164c5f --- /dev/null +++ b/benchmarks/syscall/base.yaml @@ -0,0 +1,4 @@ +suite: syscall +image: registry.gitlab.arm.com/tooling/fastpath/containers/microbench:v1.0 +params: + iterations: 10000000 diff --git a/benchmarks/syscall/getpid.yaml b/benchmarks/syscall/getpid.yaml new file mode 100644 index 0000000..e07fd34 --- /dev/null +++ b/benchmarks/syscall/getpid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: getpid +type: micro +params: + syscall: getpid diff --git a/benchmarks/syscall/getppid.yaml b/benchmarks/syscall/getppid.yaml new file mode 100644 index 0000000..8aaf02e --- /dev/null +++ b/benchmarks/syscall/getppid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: getppid +type: micro +params: + syscall: getppid diff --git a/benchmarks/syscall/invalid.yaml b/benchmarks/syscall/invalid.yaml new file mode 100644 index 0000000..b15e2a9 --- /dev/null +++ b/benchmarks/syscall/invalid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: invalid +type: micro +params: + syscall: invalid diff --git a/containers/microbench/Dockerfile b/containers/microbench/Dockerfile index 06df9f6..0e5ff27 100644 --- a/containers/microbench/Dockerfile +++ b/containers/microbench/Dockerfile @@ -28,13 +28,19 @@ RUN apt-get update && \ apt-get install --assume-yes --no-install-recommends --option=debug::pkgProblemResolver=yes \ kmod -# Compile the micromm benchmark program. ARG NAME -COPY containers/${NAME}/micromm.c /tmp/micromm.c RUN mkdir /fastpath + +# Compile the micromm benchmark program. +COPY containers/${NAME}/micromm.c /tmp/micromm.c RUN gcc /tmp/micromm.c -O2 -o /fastpath/micromm RUN rm -rf /tmp/micromm.c +# Compile the syscall benchmark program. +COPY containers/${NAME}/syscall.c /tmp/syscall.c +RUN gcc /tmp/syscall.c -O2 -o /fastpath/syscall +RUN rm -rf /tmp/syscall.c + # Setup the entrypoint. COPY containers/${NAME}/exec.py /fastpath/. CMD /fastpath/exec.py diff --git a/containers/microbench/exec.py b/containers/microbench/exec.py index 2ee800c..d85631b 100755 --- a/containers/microbench/exec.py +++ b/containers/microbench/exec.py @@ -28,31 +28,38 @@ result_header = [ def validate_benchmark(benchmark): - if benchmark["suite"] != "micromm": + if benchmark["suite"] not in ["micromm", "syscall"]: return ERR_INVAL_BENCHMARK_FORMAT params = benchmark.get("params", {}) - if benchmark["name"] == "vmalloc": - # vmalloc test. - if params and "test_case" not in params: - return ERR_INVAL_BENCHMARK_FORMAT - - found_module = ( - subprocess.run( - "modinfo test_vmalloc", - shell=True, - check=False, - capture_output=True, - ).returncode - == 0 - ) - - if not found_module: - return ERR_BENCHMARK_FAIL + if benchmark["suite"] == "micromm": + if benchmark["name"] == "vmalloc": + # vmalloc test. + if params and "test_case" not in params: + return ERR_INVAL_BENCHMARK_FORMAT + + found_module = ( + subprocess.run( + "modinfo test_vmalloc", + shell=True, + check=False, + capture_output=True, + ).returncode + == 0 + ) + + if not found_module: + return ERR_BENCHMARK_FAIL + else: + # micromm tests. + if "mode" not in params: + return ERR_INVAL_BENCHMARK_FORMAT else: - # micromm tests. - if "mode" not in params: + # syscall tests. + if "syscall" not in params: + return ERR_INVAL_BENCHMARK_FORMAT + if "iterations" not in params: return ERR_INVAL_BENCHMARK_FORMAT return ERR_NONE @@ -343,6 +350,39 @@ def test_micromm(test, outdir): } +def syscall_params_to_descs(params): + return [params] + + +def test_syscall(test, outdir): + cmd = f"/fastpath/syscall {test['syscall']} {test['iterations']}" + + log = subprocess.run( + cmd, + shell=True, + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + with open(os.path.join(outdir, "syscall.log"), "a") as logfile: + logfile.write(f"{cmd}\n") + logfile.write(log) + logfile.write("\n\n") + + parts = log.split(" ") + duration = float(parts[0].strip()) + unit = parts[1].strip() + + return { + "name": "duration", + "value": duration, + "error": ERR_NONE, + "unit": unit, + "improvement": "smaller", + } + + def make_error(errno): error = {k: None for k in result_header} error["error"] = errno @@ -367,7 +407,10 @@ def main(): outdir = os.path.join(os.path.abspath(args.fastpath_share), "output") params = benchmark.get("params", {}) - if benchmark["name"] == "vmalloc": + if benchmark["suite"] == "syscall": + params_to_descs_fn = syscall_params_to_descs + test_fn = test_syscall + elif benchmark["name"] == "vmalloc": params_to_descs_fn = vmalloc_params_to_descs test_fn = test_vmalloc else: diff --git a/containers/microbench/syscall.c b/containers/microbench/syscall.c new file mode 100644 index 0000000..36c449b --- /dev/null +++ b/containers/microbench/syscall.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include +#include + +#define INVAL_SYSCALL (-1) + +void usage(void) +{ + fprintf(stderr, "Usage: syscall [getpid|getppid|invalid] \n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + long syscall_id; + long iterations; + struct timespec start, end; + + if (argc != 3) + usage(); + if (!strcmp(argv[1], "getpid")) + syscall_id = SYS_getpid; + else if (!strcmp(argv[1], "getppid")) + syscall_id = SYS_getppid; + else if (!strcmp(argv[1], "invalid")) + syscall_id = INVAL_SYSCALL; + else + usage(); + + iterations = strtoul(argv[2], NULL, 10); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (long i = 0; i < iterations; i++) + syscall(syscall_id); + clock_gettime(CLOCK_MONOTONIC, &end); + + double elapsed = (end.tv_sec - start.tv_sec) + + (end.tv_nsec - start.tv_nsec) / 1e9; + elapsed = (elapsed / iterations) * 1000000; + printf("%f us\n", elapsed); + return 0; +} -- GitLab