affinity-inheritance: Overallocate CPU sets

Some kernels on S390 appear to return a CPU affinity mask based on
configured processors rather than the ones online.  Overallocate the CPU
set to match that, but operate only on the ones online.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Co-authored-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
This commit is contained in:
Stefan Liebler 2025-01-10 12:55:50 -05:00 committed by Siddhesh Poyarekar
parent 2ac7701888
commit 09ea1afec7
3 changed files with 19 additions and 10 deletions

View file

@ -34,10 +34,11 @@ set_my_affinity (size_t size, const cpu_set_t *set)
} }
static void static void
verify_my_affinity (int nproc, size_t size, const cpu_set_t *expected_set) verify_my_affinity (int nproc, int nproc_configured, size_t size,
const cpu_set_t *expected_set)
{ {
cpu_set_t *set = CPU_ALLOC (nproc); cpu_set_t *set = CPU_ALLOC (nproc_configured);
cpu_set_t *xor_set = CPU_ALLOC (nproc); cpu_set_t *xor_set = CPU_ALLOC (nproc_configured);
if (set == NULL || xor_set== NULL) if (set == NULL || xor_set== NULL)
FAIL_EXIT1 ("verify_my_affinity: Failed to allocate cpuset: %m\n"); FAIL_EXIT1 ("verify_my_affinity: Failed to allocate cpuset: %m\n");

View file

@ -42,6 +42,7 @@
struct test_param struct test_param
{ {
int nproc; int nproc;
int nproc_configured;
cpu_set_t *set; cpu_set_t *set;
size_t size; size_t size;
bool entry; bool entry;
@ -70,7 +71,8 @@ child_test (void *arg)
struct test_param *param = arg; struct test_param *param = arg;
printf ("%d:%d child\n", getpid (), gettid ()); printf ("%d:%d child\n", getpid (), gettid ());
verify_my_affinity (param->nproc, param->size, param->set); verify_my_affinity (param->nproc, param->nproc_configured, param->size,
param->set);
return NULL; return NULL;
} }
@ -93,7 +95,8 @@ do_one_test (void *arg)
else else
{ {
/* Verification for the first level. */ /* Verification for the first level. */
verify_my_affinity (param->nproc, param->size, param->set); verify_my_affinity (param->nproc, param->nproc_configured, param->size,
param->set);
/* Launch the second level test, launching CHILD_TEST as a subprocess and /* Launch the second level test, launching CHILD_TEST as a subprocess and
then as a subthread. Use a different mask to see if it gets then as a subthread. Use a different mask to see if it gets
@ -129,13 +132,17 @@ do_one_test (void *arg)
static int static int
do_test (void) do_test (void)
{ {
/* Large enough in case the kernel decides to return the larger mask. This
seems to happen on some kernels for S390x. */
int num_configured_cpus = get_nprocs_conf ();
int num_cpus = get_nprocs (); int num_cpus = get_nprocs ();
struct test_param param = struct test_param param =
{ {
.nproc = num_cpus, .nproc = num_cpus,
.set = CPU_ALLOC (num_cpus), .nproc_configured = num_configured_cpus,
.size = CPU_ALLOC_SIZE (num_cpus), .set = CPU_ALLOC (num_configured_cpus),
.size = CPU_ALLOC_SIZE (num_configured_cpus),
.entry = true, .entry = true,
}; };

View file

@ -34,10 +34,11 @@ set_my_affinity (size_t size, const cpu_set_t *set)
} }
static void static void
verify_my_affinity (int nproc, size_t size, const cpu_set_t *expected_set) verify_my_affinity (int nproc, int nproc_configured, size_t size,
const cpu_set_t *expected_set)
{ {
cpu_set_t *set = CPU_ALLOC (nproc); cpu_set_t *set = CPU_ALLOC (nproc_configured);
cpu_set_t *xor_set = CPU_ALLOC (nproc); cpu_set_t *xor_set = CPU_ALLOC (nproc_configured);
if (set == NULL || xor_set== NULL) if (set == NULL || xor_set== NULL)
FAIL_EXIT1 ("verify_my_affinity: Failed to allocate cpuset: %m\n"); FAIL_EXIT1 ("verify_my_affinity: Failed to allocate cpuset: %m\n");