[LTP] [PATCH] getrusage03: Pin the test to a single CPU
Jan Stancek
jstancek@redhat.com
Fri Sep 4 12:48:11 CEST 2026
The inherit_fork2 subtest fails on aarch64 systems with 64K pages and a
high CPU count: after a child touches 100 MB, ru_maxrss reports only
~64 MB, outside the 20 MB delta the test allows. Since commit
f1a7941243c1 ("mm: convert mm's rss stats into percpu_counter") the RSS
is tracked in a percpu counter whose fast read
(percpu_counter_read_positive) returns only the global count and ignores
the per-CPU caches. When a child touches memory while migrating across
many CPUs, each CPU can hold a large batch of uncounted pages, so the
sampled RSS is under-reported by tens of MB. ru_maxrss is derived from
that imprecise read, so the test observes far less than it consumed.
Pin the test process to the CPU it is currently running on before it
forks the memory-consuming children. Affinity is inherited across fork
and exec, so every descendant stays on that one CPU and at most a single
per-CPU cache is left pending, keeping the sampled RSS accurate.
Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
.../kernel/syscalls/getrusage/getrusage03.c | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/testcases/kernel/syscalls/getrusage/getrusage03.c b/testcases/kernel/syscalls/getrusage/getrusage03.c
index a2cdd6158a6c..dcd54b772613 100644
--- a/testcases/kernel/syscalls/getrusage/getrusage03.c
+++ b/testcases/kernel/syscalls/getrusage/getrusage03.c
@@ -13,10 +13,12 @@
* this program.
*/
+#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include "tst_test.h"
+#include "lapi/sched.h"
#include "getrusage03.h"
#define TESTBIN "getrusage03_child"
@@ -157,6 +159,33 @@ void (*testfunc_list[])(void) = {
zombie, sig_ign, inherit_exec
};
+/*
+ * Pin the process (and everything it forks) to the CPU it currently runs on.
+ * Since commit f1a7941243c1 ("mm: convert mm's rss stats into percpu_counter")
+ * the RSS is tracked in a percpu counter whose fast read
+ * (percpu_counter_read_positive) only returns the global count, ignoring the
+ * per-CPU caches. On many-CPU systems the caches can hold a large batch of
+ * pages each, so RSS gets under-reported by tens of MB when a child touches
+ * memory while migrating across CPUs. ru_maxrss is derived from that imprecise
+ * read, so confine the test to one CPU to keep at most a single per-CPU cache
+ * pending.
+ */
+static void setup(void)
+{
+ unsigned int cpu;
+ cpu_set_t set;
+
+ if (getcpu(&cpu, NULL))
+ tst_brk(TBROK | TERRNO, "getcpu() failed");
+
+ CPU_ZERO(&set);
+ CPU_SET(cpu, &set);
+ if (sched_setaffinity(0, sizeof(set), &set))
+ tst_brk(TBROK | TERRNO, "sched_setaffinity() failed");
+
+ tst_res(TINFO, "Pinned to CPU %u", cpu);
+}
+
static void run(unsigned int i)
{
if (!SAFE_FORK()) {
@@ -180,6 +209,7 @@ static struct tst_test test = {
{"linux-git", "1f10206cf8e945220f7220a809d8bfc15c21f9a5"},
{}
},
+ .setup = setup,
.test = run,
.tcnt = ARRAY_SIZE(testfunc_list),
.caps = (struct tst_cap []) {
--
2.55.0
More information about the ltp
mailing list