Re: [PATCH v3 03/54] selftests/mm: migration: make nthreads represent number of working threads

Luiz Capitulino
2026-04-30T13:21:43Z

On 2026-04-28 16:41, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Fixture setup sets self->nthreads to number of available CPUs minus 1
> and then each test creates 'self->nthreads - 1' threads or processes, so
> essentially nthreads counts the worker tasks and the main task.
>
> Make nthreads represent the number of spawned tasks to simplify
> thread/process creation and teardown.
>
> While on it, make the fixture setup skip the tests if there are not
> enough CPUs or NUMA nodes instead of checking this in each test.
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

Reviewed-by: Luiz Capitulino <luizcap@redhat.com>

> ---
> tools/testing/selftests/mm/migration.c | 47 +++++++++-----------------
> 1 file changed, 16 insertions(+), 31 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c
> index 7e547d945e1a..3630f2fb0800 100644
> --- a/tools/testing/selftests/mm/migration.c
> +++ b/tools/testing/selftests/mm/migration.c
> @@ -38,7 +38,7 @@ FIXTURE_SETUP(migration)
>
> if (numa_available() < 0)
> SKIP(return, "NUMA not available");
> - self->nthreads = numa_num_task_cpus() - 1;
> + self->nthreads = numa_num_task_cpus() - 2;
> self->n1 = -1;
> self->n2 = -1;
>
> @@ -52,6 +52,9 @@ FIXTURE_SETUP(migration)
> }
> }
>
> + if (self->nthreads < 1 || self->n1 < 0 || self->n2 < 0)
> + SKIP(return, "Not enough threads or NUMA nodes available");
> +
> self->threads = malloc(self->nthreads * sizeof(*self->threads));
> ASSERT_NE(self->threads, NULL);
> self->pids = malloc(self->nthreads * sizeof(*self->pids));
> @@ -127,20 +130,17 @@ TEST_F_TIMEOUT(migration, private_anon, 2*RUNTIME)
> uint64_t *ptr;
> int i;
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> ptr = mmap(NULL, TWOMEG, PROT_READ | PROT_WRITE,
> MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> ASSERT_NE(ptr, MAP_FAILED);
>
> memset(ptr, 0xde, TWOMEG);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> if (pthread_create(&self->threads[i], NULL, access_mem, ptr))
> perror("Couldn't create thread");
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(pthread_cancel(self->threads[i]), 0);
> }
>
> @@ -153,15 +153,12 @@ TEST_F_TIMEOUT(migration, shared_anon, 2*RUNTIME)
> uint64_t *ptr;
> int i;
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> ptr = mmap(NULL, TWOMEG, PROT_READ | PROT_WRITE,
> MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> ASSERT_NE(ptr, MAP_FAILED);
>
> memset(ptr, 0xde, TWOMEG);
> - for (i = 0; i < self->nthreads - 1; i++) {
> + for (i = 0; i < self->nthreads; i++) {
> pid = fork();
> if (!pid) {
> prctl(PR_SET_PDEATHSIG, SIGHUP);
> @@ -175,7 +172,7 @@ TEST_F_TIMEOUT(migration, shared_anon, 2*RUNTIME)
> }
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
> }
>
> @@ -195,9 +192,6 @@ TEST_F_TIMEOUT(migration, private_anon_thp, 2*RUNTIME)
> if (!pmdsize)
> SKIP(return, "Reading PMD pagesize failed");
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> ptr = mmap(NULL, 2 * pmdsize, PROT_READ | PROT_WRITE,
> MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> ASSERT_NE(ptr, MAP_FAILED);
> @@ -205,12 +199,12 @@ TEST_F_TIMEOUT(migration, private_anon_thp, 2*RUNTIME)
> ptr = (uint64_t *) ALIGN((uintptr_t) ptr, pmdsize);
> ASSERT_EQ(madvise(ptr, pmdsize, MADV_HUGEPAGE), 0);
> memset(ptr, 0xde, pmdsize);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> if (pthread_create(&self->threads[i], NULL, access_mem, ptr))
> perror("Couldn't create thread");
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(pthread_cancel(self->threads[i]), 0);
> }
>
> @@ -232,9 +226,6 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
> if (!pmdsize)
> SKIP(return, "Reading PMD pagesize failed");
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> ptr = mmap(NULL, 2 * pmdsize, PROT_READ | PROT_WRITE,
> MAP_SHARED | MAP_ANONYMOUS, -1, 0);
> ASSERT_NE(ptr, MAP_FAILED);
> @@ -243,7 +234,7 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
> ASSERT_EQ(madvise(ptr, pmdsize, MADV_HUGEPAGE), 0);
>
> memset(ptr, 0xde, pmdsize);
> - for (i = 0; i < self->nthreads - 1; i++) {
> + for (i = 0; i < self->nthreads; i++) {
> pid = fork();
> if (!pid) {
> prctl(PR_SET_PDEATHSIG, SIGHUP);
> @@ -257,7 +248,7 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
> }
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
> }
>
> @@ -270,9 +261,6 @@ TEST_F_TIMEOUT(migration, private_anon_htlb, 2*RUNTIME)
> uint64_t *ptr;
> int i;
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> hugepage_size = default_huge_page_size();
> if (!hugepage_size)
> SKIP(return, "Reading HugeTLB pagesize failed\n");
> @@ -282,12 +270,12 @@ TEST_F_TIMEOUT(migration, private_anon_htlb, 2*RUNTIME)
> ASSERT_NE(ptr, MAP_FAILED);
>
> memset(ptr, 0xde, hugepage_size);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> if (pthread_create(&self->threads[i], NULL, access_mem, ptr))
> perror("Couldn't create thread");
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(pthread_cancel(self->threads[i]), 0);
> }
>
> @@ -301,9 +289,6 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
> uint64_t *ptr;
> int i;
>
> - if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
> - SKIP(return, "Not enough threads or NUMA nodes available");
> -
> hugepage_size = default_huge_page_size();
> if (!hugepage_size)
> SKIP(return, "Reading HugeTLB pagesize failed\n");
> @@ -313,7 +298,7 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
> ASSERT_NE(ptr, MAP_FAILED);
>
> memset(ptr, 0xde, hugepage_size);
> - for (i = 0; i < self->nthreads - 1; i++) {
> + for (i = 0; i < self->nthreads; i++) {
> pid = fork();
> if (!pid) {
> prctl(PR_SET_PDEATHSIG, SIGHUP);
> @@ -327,7 +312,7 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
> }
>
> ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0);
> - for (i = 0; i < self->nthreads - 1; i++)
> + for (i = 0; i < self->nthreads; i++)
> ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
> }
>