The test runs one hog thread per CPU in each of three cgroups weighted
1:2:3 and expects their CPU time in the same ratio. That holds when
each CPU runs one hog of every cgroup. On a NUMA machine the load
balancer leaves them less evenly spread, and the heaviest cgroup can
fall short of the tolerance.
Pin the hogs of each cgroup one per CPU: the test checks the weights,
not the load balancer.
Fixes: 6376b22cd0a3 ("cgroup: Add test_cpucg_weight_overprovisioned() testcase")
https://virtuozzo.atlassian.net/browse/VSTOR-152674
Feature: fix selftests
Signed-off-by: Eva Kurchatova <[email protected]>
---
tools/testing/selftests/cgroup/test_cpu.c | 31 +++++++++++++++++++----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_cpu.c
b/tools/testing/selftests/cgroup/test_cpu.c
index a2b50af8e9ee..3385e75eed81 100644
--- a/tools/testing/selftests/cgroup/test_cpu.c
+++ b/tools/testing/selftests/cgroup/test_cpu.c
@@ -6,6 +6,7 @@
#include <sys/wait.h>
#include <errno.h>
#include <pthread.h>
+#include <sched.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
@@ -30,6 +31,7 @@ struct cpu_hog_func_param {
int nprocs;
struct timespec ts;
enum hog_clock_type clock_type;
+ bool pin;
};
/*
@@ -136,7 +138,13 @@ static int hog_cpus_timed(const char *cgroup, void *arg)
struct timespec ts_run = param->ts;
struct timespec ts_remaining = ts_run;
struct timespec ts_start;
- int i, ret;
+ pthread_attr_t attr;
+ cpu_set_t cpus, one;
+ int i, ret, cpu = -1;
+ /* Unpinned, as before, where the mask does not fit in a cpu_set_t */
+ bool pin = param->pin && !sched_getaffinity(0, sizeof(cpus), &cpus);
+
+ pthread_attr_init(&attr);
ret = clock_gettime(CLOCK_MONOTONIC, &ts_start);
if (ret != 0)
@@ -145,7 +153,18 @@ static int hog_cpus_timed(const char *cgroup, void *arg)
for (i = 0; i < param->nprocs; i++) {
pthread_t tid;
- ret = pthread_create(&tid, NULL, &hog_cpu_thread_func, NULL);
+ /* One hog per allowed CPU, in turn */
+ if (pin) {
+ do {
+ cpu = (cpu + 1) % CPU_SETSIZE;
+ } while (!CPU_ISSET(cpu, &cpus));
+ CPU_ZERO(&one);
+ CPU_SET(cpu, &one);
+ ret = pthread_attr_setaffinity_np(&attr, sizeof(one),
&one);
+ if (ret != 0)
+ return ret;
+ }
+ ret = pthread_create(&tid, &attr, &hog_cpu_thread_func, NULL);
if (ret != 0)
return ret;
}
@@ -372,7 +391,8 @@ run_cpucg_weight_test(
return ret;
}
-static pid_t weight_hog_ncpus(const struct cpu_hogger *child, int ncpus)
+static pid_t weight_hog_ncpus(const struct cpu_hogger *child, int ncpus,
+ bool pin)
{
long usage_seconds = 10;
struct cpu_hog_func_param param = {
@@ -382,13 +402,14 @@ static pid_t weight_hog_ncpus(const struct cpu_hogger
*child, int ncpus)
.tv_nsec = 0,
},
.clock_type = CPU_HOG_CLOCK_WALL,
+ .pin = pin,
};
return cg_run_nowait(child->cgroup, hog_cpus_timed, (void *)¶m);
}
static pid_t weight_hog_all_cpus(const struct cpu_hogger *child)
{
- return weight_hog_ncpus(child, get_nprocs());
+ return weight_hog_ncpus(child, get_nprocs(), true);
}
static int
@@ -434,7 +455,7 @@ static int test_cpucg_weight_overprovisioned(const char
*root)
static pid_t weight_hog_one_cpu(const struct cpu_hogger *child)
{
- return weight_hog_ncpus(child, 1);
+ return weight_hog_ncpus(child, 1, false);
}
static int
--
2.56.0
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel