Files
buildroot/support/testing/tests/package/test_numactl.py
Julien Olivain cc0812b6eb support/testing: test_numactl: fix test after bootlin toolchains update
Since Buildroot commit [1] "update to Bootlin toolchains 2025.08-1",
the tests.package.test_numactl fails to build its Kernel 6.1.75 with
gcc 15.1.0.

This commit fixes the issue by updating the test Kernel version to
the latest 6.1.y version (6.1.148 at the time of this commit) which
includes the fix for gcc-15.

Fixes:
https://gitlab.com/buildroot.org/buildroot/-/jobs/10984686336

[1] 947dbc92a2

Signed-off-by: Julien Olivain <ju.o@free.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2025-08-16 21:42:00 +02:00

143 lines
5.6 KiB
Python

import os
import re
import infra.basetest
class TestNumaCtl(infra.basetest.BRTest):
# A specific configuration is needed for testing numactl:
# - This test uses a x86_64 config, which has mature NUMA support.
# - A kernel need to compiled with a NUMA support.
kernel_fragment = \
infra.filepath("tests/package/test_numactl/linux-numactl.fragment")
config = \
f"""
BR2_x86_64=y
BR2_x86_corei7=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.1.148"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/x86_64/linux.config"
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kernel_fragment}"
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y
BR2_PACKAGE_NUMACTL=y
BR2_TARGET_ROOTFS_CPIO=y
BR2_TARGET_ROOTFS_CPIO_GZIP=y
# BR2_TARGET_ROOTFS_TAR is not set
"""
def check_numactl_preferred(self):
# Show the default NUMA policy settings. We check we have the
# 4 physical cpus on 2 nodes we configured the emulator
# command line.
out, ret = self.emulator.run("numactl --show")
self.assertEqual(ret, 0)
checks = [
"policy: default",
"preferred node: current",
"physcpubind: 0 1 2 3 ",
"nodebind: 0 1 ",
"membind: 0 1 "
]
for pattern in checks:
self.assertIn(pattern, out)
# Check the preferred policy on different nodes. This command
# is taken from the numactl man page.
for pref_node in range(2):
cmd = f"numactl --preferred={pref_node} numactl --show"
out, ret = self.emulator.run(cmd)
self.assertEqual(ret, 0)
checks = [
"policy: preferred",
f"preferred node: {pref_node}"
]
for pattern in checks:
self.assertIn(pattern, out)
def get_numa_node_free_mem(self):
out, ret = self.emulator.run("numactl --hardware")
self.assertEqual(ret, 0)
free_mem = {}
p = re.compile("^node ([0-9]+) free: ([0-9]+) MB")
for line in out:
m = p.match(line)
if m:
node = int(m.group(1))
mem = int(m.group(2))
free_mem[node] = mem
return free_mem
def check_numactl_membind(self):
# We get the current amount of free memory on each node, for
# later comparison.
initial_node_free_mem = self.get_numa_node_free_mem()
# We allocate a shared memory file with a restriction to be in
# node 1 memory only.
shm_file = "/dev/shm/file"
file_size = 100
cmd = f"numactl --membind=1 dd if=/dev/zero of={shm_file} bs=1M count={file_size}"
self.assertRunOk(cmd)
# We collect again the amount of free memory per node.
node_free_mem = self.get_numa_node_free_mem()
# Since we allocated 100M on node 1 only, we check the free
# space on node 0 did not significantly changed and on node 1
# approximately reduced of the file size.
diff = initial_node_free_mem[0] - node_free_mem[0]
self.assertAlmostEqual(diff, 0, delta=10)
diff = initial_node_free_mem[1] - node_free_mem[1]
self.assertAlmostEqual(diff, file_size, delta=10)
# Remove the file, to free the memory.
self.assertRunOk(f"rm -f {shm_file}")
# We allocate again a file in shared memory, but this time in
# two chunks. Each chunk is requested to be allocated in two
# different nodes. This example is taken from the numactl man
# page.
chunk_size = file_size // 2
cmd = "numactl --membind=0 "
cmd += f"dd if=/dev/zero of={shm_file} bs=1M count={chunk_size}"
self.assertRunOk(cmd)
cmd = "numactl --membind=1 "
cmd += f"dd if=/dev/zero of={shm_file} bs=1M count={chunk_size} seek={chunk_size}"
self.assertRunOk(cmd)
# We collect again the amount of free memory.
node_free_mem = self.get_numa_node_free_mem()
# We check the free memory space approximately reduced of each
# chunk size.
for node in range(2):
free_mem_diff = initial_node_free_mem[node] - node_free_mem[node]
self.assertAlmostEqual(free_mem_diff, chunk_size, delta=5)
def test_run(self):
img = os.path.join(self.builddir, "images", "rootfs.cpio.gz")
kern = os.path.join(self.builddir, "images", "bzImage")
# We start the Qemu emulator with 4 processors on 2 NUMA nodes.
self.emulator.boot(arch="x86_64",
kernel=kern,
kernel_cmdline=["console=ttyS0"],
options=["-cpu", "Nehalem", "-m", "512M",
"-smp", "cpus=4,sockets=2,cores=2,maxcpus=4",
"-object", "memory-backend-ram,size=256M,id=m0",
"-object", "memory-backend-ram,size=256M,id=m1",
"-numa", "node,cpus=0-1,nodeid=0,memdev=m0",
"-numa", "node,cpus=2-3,nodeid=1,memdev=m1",
"-initrd", img])
self.emulator.login()
# Check a simple numactl invication:
# show the NUMA hardware inventory.
self.assertRunOk("numactl --hardware")
self.check_numactl_preferred()
self.check_numactl_membind()