From e456c835369f0d06134fbb3ca516f931d2cd5c5b Mon Sep 17 00:00:00 2001 From: Daniel Hodges Date: Fri, 11 Oct 2024 20:27:44 -0700 Subject: [PATCH] scx_layered: Add topology integration test Add a bpftrace script that does a topology aware test. The test script runs a bpftrace script that asserts that stress-ng processes are scheduled on NUMA node 0 only. Signed-off-by: Daniel Hodges --- .../scx_layered/integration/layer_node.bt | 48 +++++++++++++++++++ scheds/rust/scx_layered/integration/numa.json | 43 +++++++++++++++++ .../scx_layered/integration/numa_tests.sh | 32 +++++++++++++ 3 files changed, 123 insertions(+) create mode 100755 scheds/rust/scx_layered/integration/layer_node.bt create mode 100644 scheds/rust/scx_layered/integration/numa.json create mode 100755 scheds/rust/scx_layered/integration/numa_tests.sh diff --git a/scheds/rust/scx_layered/integration/layer_node.bt b/scheds/rust/scx_layered/integration/layer_node.bt new file mode 100755 index 0000000..662ee9b --- /dev/null +++ b/scheds/rust/scx_layered/integration/layer_node.bt @@ -0,0 +1,48 @@ +#!/usr/bin/env -S bpftrace --unsafe -q + +/* + * Asserts that the `node` layer config works properly by failing if the pid + * passed to the script runs on NUMA node 1. The layered config should restrict + * the pid passed to the script to run on a layer that only runs on NUMA node 0. + */ + +BEGIN +{ + @bpftrace_pid = pid; + @sig = 0; + + if ($1 == 0) { + // exit 137 + @sig = 9; + } +} + +profile:hz:1 +{ + @counts[cpu] = @counts[cpu] + 1; + if (@counts[cpu] == 15) { + // exit 0 + @sig = 15; + } +} + +rawtracepoint:sched_switch +{ + $task = (struct task_struct *)arg1; + + if (($task->parent->pid == $1 && numaid == 1) || + ($task->real_parent->pid == $1 && numaid == 1)) { + // exit 137 + @sig = 9; + } +} + +kprobe:__x64_sys_* / @bpftrace_pid == pid / { + if (@sig > 0) { + signal(@sig); + } +} + +interval:s:1 { + print(("bpftrace monitoring pid", $1, "signal", @sig)); +} diff --git a/scheds/rust/scx_layered/integration/numa.json b/scheds/rust/scx_layered/integration/numa.json new file mode 100644 index 0000000..1ce161e --- /dev/null +++ b/scheds/rust/scx_layered/integration/numa.json @@ -0,0 +1,43 @@ +[ + { + "name": "numa_0", + "comment": "numa0", + "matches": [ + [ + { + "CommPrefix": "stress-ng" + } + ], + [ + { + "PcommPrefix": "stress-ng" + } + ] + ], + "kind": { + "Confined": { + "util_range": [ + 0.4, + 0.90 + ], + "growth_algo": "Linear", + "nodes": [ + 0 + ] + } + } + }, + { + "name": "reset", + "comment": "the rest", + "matches":[[]], + "kind": { + "Grouped": { + "util_range": [ + 0.05, + 0.60 + ] + } + } + } +] diff --git a/scheds/rust/scx_layered/integration/numa_tests.sh b/scheds/rust/scx_layered/integration/numa_tests.sh new file mode 100755 index 0000000..9e8b260 --- /dev/null +++ b/scheds/rust/scx_layered/integration/numa_tests.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +layered_bin=${1:-../../../../target/release/scx_layered} +test_scripts=( "layer_node.bt" ) + +for test_script in "${test_scripts[@]}"; do + sudo pkill -9 -f scx_layered + sudo "${layered_bin}" --stats 1 f:numa.json -v & + layered_pid=$! + + echo "layered pid ${layered_pid}" + sleep 2 + + stress-ng -c 2 -f 1 -t 30 & + stress_pid=$! + + echo "stress-ng pid ${stress_pid}" + sleep 1 + + sudo "./${test_script}" "${stress_pid}" + test_exit=$? + + pidof scx_layered && sudo pkill -9 -f scx_layered + # always cleanup stress-ng + sudo pkill -9 -f stress-ng + + if [ $test_exit -ne 0 ]; then + echo "test script ${test_script} failed: ${test_exit}" + exit $test_exit; + fi + echo "test script ${test_script} passed: ${test_exit}" +done