From: Albert Esteve <aesteve@redhat.com>
To: "Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Michal Koutný" <mkoutny@suse.com>,
"Shuah Khan" <shuah@kernel.org>
Cc: linux-kernel@vger.kernel.org, cgroups@vger.kernel.org,
linux-kselftest@vger.kernel.org,
Albert Esteve <aesteve@redhat.com>
Subject: [PATCH v5 3/4] selftests: cgroup: Add vmtest-dmem runner script
Date: Mon, 06 Jul 2026 14:06:42 +0200 [thread overview]
Message-ID: <20260706-kunit_cgroups-v5-3-6c42c8753468@redhat.com> (raw)
In-Reply-To: <20260706-kunit_cgroups-v5-0-6c42c8753468@redhat.com>
Currently, test_dmem relies on the dmem_selftest helper module
and a VM setup that may not have the helper preinstalled.
This makes automated coverage of dmem charge paths harder in
virtme-based runs.
Add tools/testing/selftests/cgroup/vmtest-dmem.sh to provide a
repeatable VM workflow for dmem tests. The script uses vng --exec
to run the test directly inside a virtme-ng guest with minimal
setup.
The script boots a virtme-ng guest, validates dmem controller
availability, ensures the dmem helper path is present, and runs
tools/testing/selftests/cgroup/test_dmem. If the helper is not
available as a loaded module, it attempts module build/load for
the running guest kernel before executing the test binary.
The runner also supports interactive shell mode (-s) and reuses
the verbosity and KTAP exit-code conventions used by other vmtest
scripts, so it integrates with existing kselftest workflows.
vmtest-dmem.sh is placed in TEST_FILES rather than TEST_PROGS so
it is installed alongside the test suite but not invoked
automatically by run_kselftest.sh. It requires a VM-capable host
and is intended to be run manually.
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
tools/testing/selftests/cgroup/Makefile | 2 +-
tools/testing/selftests/cgroup/vmtest-dmem.sh | 149 ++++++++++++++++++++++++++
2 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/Makefile b/tools/testing/selftests/cgroup/Makefile
index e1a5e9316620e..2c407710c6e3b 100644
--- a/tools/testing/selftests/cgroup/Makefile
+++ b/tools/testing/selftests/cgroup/Makefile
@@ -3,7 +3,7 @@ CFLAGS += -Wall -pthread
all: ${HELPER_PROGS}
-TEST_FILES := with_stress.sh
+TEST_FILES := with_stress.sh vmtest-dmem.sh
TEST_PROGS := test_stress.sh test_cpuset_prs.sh test_cpuset_v1_hp.sh
TEST_GEN_FILES := wait_inotify
# Keep the lists lexicographically sorted
diff --git a/tools/testing/selftests/cgroup/vmtest-dmem.sh b/tools/testing/selftests/cgroup/vmtest-dmem.sh
new file mode 100755
index 0000000000000..0bb6529112b54
--- /dev/null
+++ b/tools/testing/selftests/cgroup/vmtest-dmem.sh
@@ -0,0 +1,149 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2026 Red Hat, Inc.
+#
+# Run cgroup test_dmem inside a virtme-ng VM.
+# Dependencies:
+# * virtme-ng
+# * qemu (used by virtme-ng)
+
+set -euo pipefail
+
+readonly SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+readonly KERNEL_CHECKOUT="$(realpath "${SCRIPT_DIR}"/../../../../)"
+
+source "${SCRIPT_DIR}"/../kselftest/ktap_helpers.sh
+
+QEMU="qemu-system-$(uname -m)"
+VERBOSE=0
+SHELL_MODE=0
+GUEST_TREE="${GUEST_TREE:-$KERNEL_CHECKOUT}"
+
+VM_SCRIPT=""
+
+function usage() {
+ cat <<EOF
+$0 [OPTIONS]
+Options:
+ -q QEMU binary/path (default: ${QEMU})
+ -s Start interactive shell in VM instead of running tests
+ -v Verbose output (vng boot logs on stdout)
+ -h Display this help
+EOF
+}
+
+function cleanup() {
+ rm -f "${VM_SCRIPT}"
+}
+trap cleanup EXIT
+
+function skip() {
+ local msg=${1:-""}
+
+ ktap_test_skip "${msg}"
+ exit "${KSFT_SKIP}"
+}
+
+function fail() {
+ local msg=${1:-""}
+
+ ktap_test_fail "${msg}"
+ exit "${KSFT_FAIL}"
+}
+
+function check_deps() {
+ for dep in vng "${QEMU}"; do
+ if ! command -v "${dep}" >/dev/null 2>&1; then
+ skip "dependency ${dep} not found"
+ fi
+ done
+}
+
+# Run vng with common flags. Extra arguments are appended by the caller:
+# --exec <script> for automated test runs
+# (nothing) for interactive shell mode
+function run_vm() {
+ local verbose_opt=""
+
+ [[ "${VERBOSE}" -eq 1 ]] && verbose_opt="--verbose"
+
+ vng \
+ --run \
+ ${verbose_opt:+"${verbose_opt}"} \
+ --qemu="$(command -v "${QEMU}")" \
+ --user root \
+ --rw \
+ "$@"
+}
+
+function main() {
+ while getopts ':hvq:s' opt; do
+ case "${opt}" in
+ v) VERBOSE=1 ;;
+ q) QEMU="${OPTARG}" ;;
+ s) SHELL_MODE=1 ;;
+ h) usage; exit 0 ;;
+ *) usage; exit 1 ;;
+ esac
+ done
+
+ check_deps
+
+ if [[ "${SHELL_MODE}" -eq 1 ]]; then
+ echo "Starting interactive shell in VM. Exit to stop VM."
+ run_vm
+ exit 0
+ fi
+
+ # Write the VM-side script into the script directory so it is
+ # accessible in the guest via the --rw host filesystem mount.
+ VM_SCRIPT="$(mktemp --suffix=.sh "${SCRIPT_DIR}/.dmem_vmtest_XXXX")"
+
+ cat > "${VM_SCRIPT}" << EOF
+#!/bin/bash
+set -euo pipefail
+
+mountpoint -q /sys/kernel/debug || mount -t debugfs none /sys/kernel/debug
+
+# Verify cgroup controllers are available.
+if ! grep -q dmem /sys/fs/cgroup/cgroup.controllers || \
+ ! grep -q memory /sys/fs/cgroup/cgroup.controllers; then
+ echo "guest kernel missing CONFIG_CGROUP_DMEM or CONFIG_MEMCG" >&2
+ exit 1
+fi
+
+# Load dmem_selftest: try built-in, then modprobe, then build + insmod.
+if [[ -e /sys/kernel/debug/dmem_selftest/charge ]]; then
+ echo "dmem_selftest ready (built-in or already loaded)"
+elif modprobe -q dmem_selftest 2>/dev/null && \
+ [[ -e /sys/kernel/debug/dmem_selftest/charge ]]; then
+ echo "dmem_selftest ready (modprobe)"
+else
+ kdir="/lib/modules/\$(uname -r)/build"
+ if [[ -d "\$kdir" ]]; then
+ echo "Building dmem_selftest.ko against running guest kernel..."
+ if make -C "\$kdir" M="${GUEST_TREE}/kernel/cgroup" \
+ CONFIG_DMEM_SELFTEST=m modules; then
+ insmod "${GUEST_TREE}/kernel/cgroup/dmem_selftest.ko" \
+ 2>/dev/null || modprobe -q dmem_selftest 2>/dev/null || true
+ fi
+ fi
+ if [[ ! -e /sys/kernel/debug/dmem_selftest/charge ]]; then
+ echo "dmem_selftest unavailable (modprobe/build+insmod failed)" >&2
+ exit 1
+ fi
+ echo "dmem_selftest ready (built + insmod)"
+fi
+
+echo "Running cgroup/test_dmem in VM..."
+cd "${GUEST_TREE}"
+make -C tools/testing/selftests TARGETS=cgroup
+./tools/testing/selftests/cgroup/test_dmem
+EOF
+
+ echo "Booting virtme-ng VM..."
+ run_vm --exec "bash ${VM_SCRIPT}"
+}
+
+main "$@"
--
2.54.0
next prev parent reply other threads:[~2026-07-06 12:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 12:06 [PATCH v5 0/4] cgroup: dmem: add selftest helper, coverage, and VM runner Albert Esteve
2026-07-06 12:06 ` [PATCH v5 1/4] cgroup: Add dmem_selftest module Albert Esteve
2026-07-06 12:06 ` [PATCH v5 2/4] selftests: cgroup: Add dmem selftest coverage Albert Esteve
2026-07-06 12:06 ` Albert Esteve [this message]
2026-07-06 12:06 ` [PATCH v5 4/4] selftests: cgroup: handle vmtest-dmem -b to test locally built kernel Albert Esteve
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=20260706-kunit_cgroups-v5-3-6c42c8753468@redhat.com \
--to=aesteve@redhat.com \
--cc=cgroups@vger.kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mkoutny@suse.com \
--cc=shuah@kernel.org \
--cc=tj@kernel.org \
/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