From acf18c1bb4fdf8d4d866ab4ebfb509a6215a0d77 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Wed, 31 Jul 2024 11:53:01 +0200 Subject: [PATCH] Make nOS-V kernel overflow test configurable --- test/rt/nosv/CMakeLists.txt | 11 ++++- test/rt/nosv/overflow-kernel-ring.c | 41 +++++++++--------- test/rt/nosv/overflow-kernel-ring.driver.sh | 46 +++++++++++++++++++++ 3 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 test/rt/nosv/overflow-kernel-ring.driver.sh diff --git a/test/rt/nosv/CMakeLists.txt b/test/rt/nosv/CMakeLists.txt index 00d3b80..bc6f457 100644 --- a/test/rt/nosv/CMakeLists.txt +++ b/test/rt/nosv/CMakeLists.txt @@ -44,7 +44,6 @@ nosv_test(parallel-tasks.c SORT) nosv_test(inline.c SORT) nosv_test(mutex.c SORT LEVEL 3) nosv_test(barrier.c SORT LEVEL 3) -nosv_test(overflow-kernel-ring.c SORT LEVEL 3) # Test multiple instrumentation levels nosv_test(several-tasks.c SORT NAME several-tasks-level-0 LEVEL 0) @@ -63,3 +62,13 @@ nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREA # From level 3 up the breakdown can be enabled nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-3 LEVEL 3 BREAKDOWN) nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN) + +include(CheckPerfParanoid) +if (PERF_PARANOID_KERNEL) + message(STATUS "Enabling perf paranoid tests for nOS-V") + nosv_test(overflow-kernel-ring.c DRIVER "overflow-kernel-ring.driver.sh") +elseif(ENABLE_ALL_TESTS) + message(FATAL_ERROR "Cannot enable perf paranoid tests for nOS-V") +else() + message(STATUS "Disabling perf paranoid tests for nOS-V") +endif() diff --git a/test/rt/nosv/overflow-kernel-ring.c b/test/rt/nosv/overflow-kernel-ring.c index 03a070f..993cc3d 100644 --- a/test/rt/nosv/overflow-kernel-ring.c +++ b/test/rt/nosv/overflow-kernel-ring.c @@ -5,47 +5,44 @@ #include #include #include +#include +#include #include "common.h" #include "compat.h" int done = 0; - -/* https://gitlab.bsc.es/nos-v/nos-v/-/blob/master/src/include/instr.h?ref_type=heads#L542 */ -#define NOSV_INSTR_KBUFLEN (4UL * 1024UL * 1024UL) // 4 MB +unsigned long ncs = 0; +unsigned long nflush = 0; static void task_run(nosv_task_t task) { UNUSED(task); - /* Cause enough context switches for the kernel ring to be full, - * which wouldn't fail if nosv_waitfor() flushes the kernel - * events. */ - - unsigned long fill = 3 * NOSV_INSTR_KBUFLEN / 4; - unsigned long n = fill / 16; - struct timespec one_ns = { .tv_sec = 0, .tv_nsec = 1 }; - for (unsigned long run = 0; run < 3; run++) { - info("starting run %lu", run); - for (unsigned long i = 0; i < n; i++) - nanosleep(&one_ns, NULL); - - info("starting waitfor"); - - if (nosv_waitfor(1, NULL) != 0) - die("nosv_waitfor failed"); - - info("end run %lu", run); + for (unsigned long i = 1; i <= ncs; i++) { + nanosleep(&one_ns, NULL); + /* Make a total of 16 waitfor calls to flush the ring buffer */ + if (i % nflush == 0) { + info("flusing at %lu", i); + if (nosv_waitfor(1, NULL) != 0) + die("nosv_waitfor failed"); + } } done = 1; } -int main(void) +int main(int argc, char *argv[]) { + if (argc != 3) + die("usage: %s \n", argv[0]); + + ncs = (unsigned long) atol(argv[1]); + nflush = (unsigned long) atol(argv[2]); + if (nosv_init()) die("nosv_init failed"); diff --git a/test/rt/nosv/overflow-kernel-ring.driver.sh b/test/rt/nosv/overflow-kernel-ring.driver.sh new file mode 100644 index 0000000..40a90ec --- /dev/null +++ b/test/rt/nosv/overflow-kernel-ring.driver.sh @@ -0,0 +1,46 @@ +target=$OVNI_TEST_BIN + +# We will set our own +unset NOSV_CONFIG +unset NOSV_CONFIG_OVERRIDE + +export NOSV_APPID=1 + +# Small kernel ring size to make execution fast +ringsize=$((64*1024)) + +# Each CS event pair occupies 16 bytes. +cspair=32 + +# How many CS event pairs fit in the ring buffer? +navail=$(($ringsize / $cspair)) + +# For the test, write 8 times the ring buffer +ncs=$((8 * $navail)) + +# Flush the kernel after writing 1/4 of the ring buffer. +nflush=$(($ringsize / $cspair / 4)) + +cat > nosv.toml << EOF +instrumentation.version = "ovni" +ovni.level = 3 +ovni.kernel_ringsize = ${ringsize} +EOF + +$target $ncs $nflush 2>&1 | tee err.log + +# Ensure no nOS-V warnings at runtime +if grep -c "cannot enable kernel events" err.log; then + echo "cannot enable kernel events in all threads" >&2 + exit 1 +fi + +# We need to sort the trace as it has unsorted regions +ovnisort ovni + +# Ensure we have at least the number of context switches we caused, and ensure +# the number of "in" and "out" events match. +ovnitop ovni | awk '{n[$1] = $2} END { if (n["KCO"] != n["KCI"] || n["KCO"] < '$ncs') exit 1 }' + +# Run the emulator +ovniemu -l ovni