* [PATCH v2 0/2] KVM: selftest: Fix steal time w/ non-glibc builds
@ 2026-07-07 15:07 Sean Christopherson
2026-07-07 15:07 ` [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np() Sean Christopherson
2026-07-07 15:07 ` [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test Sean Christopherson
0 siblings, 2 replies; 7+ messages in thread
From: Sean Christopherson @ 2026-07-07 15:07 UTC (permalink / raw)
To: Paolo Bonzini
Cc: kvm, linux-kernel, Hisam Mehboob, Aqib Faruqui,
Sean Christopherson
Remove unnecessary usage of pthread_attr_setaffinity_np() in the steal time
test so that it can build against non-glibc libraries, and opportunistically
expand the test coverage by pinning the test threads to a random pCPU instead
of hardcoding the pin to pCPU0.
v2:
- Rely on CPU affinity inheritance. [Sashiko]
- Add a patch to in to a random CPU instead of CPU0.
v1: https://lore.kernel.org/all/20260706163649.155548-1-hisamshar@gmail.com
Sean Christopherson (2):
KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np()
KVM: selftests: Randomize pCPU in steal time test
tools/testing/selftests/kvm/steal_time.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
base-commit: a204badd8432f93b7e862e7dac6db0fe3d65f370
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np()
2026-07-07 15:07 [PATCH v2 0/2] KVM: selftest: Fix steal time w/ non-glibc builds Sean Christopherson
@ 2026-07-07 15:07 ` Sean Christopherson
2026-07-07 15:21 ` sashiko-bot
2026-07-07 15:07 ` [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test Sean Christopherson
1 sibling, 1 reply; 7+ messages in thread
From: Sean Christopherson @ 2026-07-07 15:07 UTC (permalink / raw)
To: Paolo Bonzini
Cc: kvm, linux-kernel, Hisam Mehboob, Aqib Faruqui,
Sean Christopherson
In the steal time test, don't explicitly set the CPU affinity mask of the
worker child and instead rely on the child inheriting the affinity of the
main thread. Per the pthread_create()[1] and pthread_setaffinity_np()[2]
documentation, new threads inherit the parent's affinity mask.
Linux-specific details
The new thread inherits copies of the calling thread's capability
sets (see capabilities(7)) and CPU affinity mask (see
sched_setaffinity(2)).
Out of an abundance of caution, assert that the child did indeed inherit
the CPU affinity mask, as the test will hang indefinitely if the system is
under light load.
Dropping use of pthread_attr_setaffinity_np() allows building the steal
time test against non-glibc C libraries that don't implement that GNU
extension.
Link: https://man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html [1]
Link: https://man7.org/linux/man-pages/man3/pthread_create.3.html [1]
Cc: Hisam Mehboob <hisamshar@gmail.com>
Reported-by: Aqib Faruqui <aqibaf@amazon.com>
Closes: https://lore.kernel.org/all/20250829142556.72577-4-aqibaf@amazon.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/steal_time.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
index 76fcdd1fd3cb..a244bf9f701f 100644
--- a/tools/testing/selftests/kvm/steal_time.c
+++ b/tools/testing/selftests/kvm/steal_time.c
@@ -508,7 +508,6 @@ int main(int ac, char **av)
{
struct kvm_vcpu *vcpus[NR_VCPUS];
struct kvm_vm *vm;
- pthread_attr_t attr;
pthread_t thread;
cpu_set_t cpuset;
unsigned int gpages;
@@ -522,8 +521,6 @@ int main(int ac, char **av)
/* Set CPU affinity so we can force preemption of the VCPU */
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
- pthread_attr_init(&attr);
- pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
/* Create a VM and an identity mapped memslot for the steal time structure */
@@ -558,7 +555,11 @@ int main(int ac, char **av)
/* Steal time from the VCPU. The steal time thread has the same CPU affinity as the VCPUs. */
run_delay = get_run_delay();
- pthread_create(&thread, &attr, do_steal_time, NULL);
+ pthread_create(&thread, NULL, do_steal_time, NULL);
+ pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
+ TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(0, &cpuset),
+ "Worker failed to inherit parent's CPU affinity");
+
do
sched_yield();
while (get_run_delay() - run_delay < MIN_RUN_DELAY_NS);
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test
2026-07-07 15:07 [PATCH v2 0/2] KVM: selftest: Fix steal time w/ non-glibc builds Sean Christopherson
2026-07-07 15:07 ` [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np() Sean Christopherson
@ 2026-07-07 15:07 ` Sean Christopherson
2026-07-07 15:29 ` sashiko-bot
1 sibling, 1 reply; 7+ messages in thread
From: Sean Christopherson @ 2026-07-07 15:07 UTC (permalink / raw)
To: Paolo Bonzini
Cc: kvm, linux-kernel, Hisam Mehboob, Aqib Faruqui,
Sean Christopherson
Pin the steal time test's tasks to a random pCPU in the system instead of
hardcoding the test to always run on pCPU0 as a cheap way of increasing
test coverage, and to do the "right thing" if the parent task of the test
doesn't have pCPU0 in its CPU affinity mask.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/steal_time.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
index a244bf9f701f..92e7ffcd68b7 100644
--- a/tools/testing/selftests/kvm/steal_time.c
+++ b/tools/testing/selftests/kvm/steal_time.c
@@ -514,14 +514,12 @@ int main(int ac, char **av)
long stolen_time;
long run_delay;
bool verbose;
- int i;
+ int i, cpu;
verbose = ac > 1 && (!strncmp(av[1], "-v", 3) || !strncmp(av[1], "--verbose", 10));
/* Set CPU affinity so we can force preemption of the VCPU */
- CPU_ZERO(&cpuset);
- CPU_SET(0, &cpuset);
- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+ cpu = pin_self_to_any_cpu();
/* Create a VM and an identity mapped memslot for the steal time structure */
vm = vm_create_with_vcpus(NR_VCPUS, guest_code, vcpus);
@@ -557,7 +555,7 @@ int main(int ac, char **av)
run_delay = get_run_delay();
pthread_create(&thread, NULL, do_steal_time, NULL);
pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
- TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(0, &cpuset),
+ TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(cpu, &cpuset),
"Worker failed to inherit parent's CPU affinity");
do
--
2.55.0.rc2.803.g1fd1e6609c-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np()
2026-07-07 15:07 ` [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np() Sean Christopherson
@ 2026-07-07 15:21 ` sashiko-bot
2026-07-07 16:03 ` Sean Christopherson
0 siblings, 1 reply; 7+ messages in thread
From: sashiko-bot @ 2026-07-07 15:21 UTC (permalink / raw)
To: Sean Christopherson; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The assertion intended to verify CPU affinity inheritance can silently pass if `pthread_getaffinity_np` fails, because `cpuset` is not cleared before the call and its return value is ignored.
--
--- Patch [1]: [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np() ---
commit 4058c4b23733ee3e6fc2f4b8ebc85f63f4492c52
Author: Sean Christopherson <seanjc@google.com>
KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np()
This commit removes explicit CPU affinity setting for the worker child thread
in the steal time test, relying on inheritance from the parent thread instead.
It adds an assertion to verify the affinity was properly inherited. It also
allows the test to build against non-glibc C libraries lacking
pthread_attr_setaffinity_np().
Link: https://man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html [1]
Link: https://man7.org/linux/man-pages/man3/pthread_create.3.html [1]
Closes: https://lore.kernel.org/all/20250829142556.72577-4-aqibaf@amazon.com
> diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
> index 76fcdd1fd3cb4..a244bf9f701f7 100644
> --- a/tools/testing/selftests/kvm/steal_time.c
> +++ b/tools/testing/selftests/kvm/steal_time.c
[ ... ]
> @@ -558,7 +555,11 @@ int main(int ac, char **av)
>
> /* Steal time from the VCPU. The steal time thread has the same CPU affinity as the VCPUs. */
> run_delay = get_run_delay();
> - pthread_create(&thread, &attr, do_steal_time, NULL);
> + pthread_create(&thread, NULL, do_steal_time, NULL);
> + pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
[Severity: Medium]
Can this assertion spuriously pass if pthread_getaffinity_np() fails?
Because cpuset is not cleared before calling pthread_getaffinity_np() in
main(), and the return value isn't checked, cpuset will retain its previous
value if the call fails. This could happen if the child thread completes
its execution before pthread_getaffinity_np() is called.
Since cpuset was already populated with CPU 0 earlier in main(), the
TEST_ASSERT would read the stale data and pass even if the thread did not
inherit the affinity.
> + TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(0, &cpuset),
> + "Worker failed to inherit parent's CPU affinity");
> +
> do
> sched_yield();
> while (get_run_delay() - run_delay < MIN_RUN_DELAY_NS);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260707150706.1198541-1-seanjc@google.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test
2026-07-07 15:07 ` [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test Sean Christopherson
@ 2026-07-07 15:29 ` sashiko-bot
2026-07-07 16:15 ` Sean Christopherson
0 siblings, 1 reply; 7+ messages in thread
From: sashiko-bot @ 2026-07-07 15:29 UTC (permalink / raw)
To: Sean Christopherson; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Uninitialized variable read leading to test flakes if pthread_getaffinity_np() fails.
--
--- Patch [2]: [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test ---
commit 0d5df2335fea13e6ab9b9a76b38f38b87bb2fb85
Author: Sean Christopherson <seanjc@google.com>
KVM: selftests: Randomize pCPU in steal time test
This commit updates the steal time test to pin its tasks to a random pCPU
instead of hardcoding pCPU0. It aims to increase test coverage and properly
handle parent tasks that lack pCPU0 in their CPU affinity mask.
> diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
> --- a/tools/testing/selftests/kvm/steal_time.c
> +++ b/tools/testing/selftests/kvm/steal_time.c
[ ... ]
> @@ -514,14 +514,12 @@ int main(int ac, char **av)
> long stolen_time;
> long run_delay;
> bool verbose;
> - int i;
> + int i, cpu;
>
> verbose = ac > 1 && (!strncmp(av[1], "-v", 3) || !strncmp(av[1], "--verbose", 10));
>
> /* Set CPU affinity so we can force preemption of the VCPU */
> - CPU_ZERO(&cpuset);
> - CPU_SET(0, &cpuset);
> - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
> + cpu = pin_self_to_any_cpu();
>
> /* Create a VM and an identity mapped memslot for the steal time structure */
> vm = vm_create_with_vcpus(NR_VCPUS, guest_code, vcpus);
[ ... ]
> @@ -557,7 +555,7 @@ int main(int ac, char **av)
> run_delay = get_run_delay();
> pthread_create(&thread, NULL, do_steal_time, NULL);
> pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
> - TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(0, &cpuset),
> + TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(cpu, &cpuset),
[Severity: Medium]
Is there a race condition here if the worker thread exits before the parent
reads its affinity?
When pthread_create() spawns the worker thread, the child runs for a short
duration and exits. If the parent thread is preempted right after creation,
the child might finish its work and exit before pthread_getaffinity_np()
executes in the parent.
If the kernel task is already gone, pthread_getaffinity_np() will fail with
ESRCH. Because the explicit initialization of cpuset was removed earlier in
main(), cpuset remains completely uninitialized.
Could this cause CPU_COUNT() and CPU_ISSET() to evaluate garbage stack memory
and trigger sporadic TEST_ASSERT failures? Should the return value of
pthread_getaffinity_np() be checked, or should cpuset be initialized before
the call?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260707150706.1198541-1-seanjc@google.com?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np()
2026-07-07 15:21 ` sashiko-bot
@ 2026-07-07 16:03 ` Sean Christopherson
0 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2026-07-07 16:03 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvm
On Tue, Jul 07, 2026, sashiko-bot@kernel.org wrote:
> > diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
> > index 76fcdd1fd3cb4..a244bf9f701f7 100644
> > --- a/tools/testing/selftests/kvm/steal_time.c
> > +++ b/tools/testing/selftests/kvm/steal_time.c
>
> [ ... ]
>
> > @@ -558,7 +555,11 @@ int main(int ac, char **av)
> >
> > /* Steal time from the VCPU. The steal time thread has the same CPU affinity as the VCPUs. */
> > run_delay = get_run_delay();
> > - pthread_create(&thread, &attr, do_steal_time, NULL);
> > + pthread_create(&thread, NULL, do_steal_time, NULL);
> > + pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
>
> [Severity: Medium]
> Can this assertion spuriously pass if pthread_getaffinity_np() fails?
Yes, but that "flaw" is "fixed" in the next patch. All in quotes because IMO
neither scenario is truly problematic.
> Because cpuset is not cleared before calling pthread_getaffinity_np() in
> main(), and the return value isn't checked, cpuset will retain its previous
> value if the call fails. This could happen if the child thread completes
> its execution before pthread_getaffinity_np() is called.
No, because the underlying kernel task is alive until pthread_join().
> Since cpuset was already populated with CPU 0 earlier in main(), the
> TEST_ASSERT would read the stale data and pass even if the thread did not
> inherit the affinity.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test
2026-07-07 15:29 ` sashiko-bot
@ 2026-07-07 16:15 ` Sean Christopherson
0 siblings, 0 replies; 7+ messages in thread
From: Sean Christopherson @ 2026-07-07 16:15 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvm
On Tue, Jul 07, 2026, sashiko-bot@kernel.org wrote:
> > diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
> > --- a/tools/testing/selftests/kvm/steal_time.c
> > +++ b/tools/testing/selftests/kvm/steal_time.c
> [ ... ]
> > @@ -514,14 +514,12 @@ int main(int ac, char **av)
> > long stolen_time;
> > long run_delay;
> > bool verbose;
> > - int i;
> > + int i, cpu;
> >
> > verbose = ac > 1 && (!strncmp(av[1], "-v", 3) || !strncmp(av[1], "--verbose", 10));
> >
> > /* Set CPU affinity so we can force preemption of the VCPU */
> > - CPU_ZERO(&cpuset);
> > - CPU_SET(0, &cpuset);
> > - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
> > + cpu = pin_self_to_any_cpu();
> >
> > /* Create a VM and an identity mapped memslot for the steal time structure */
> > vm = vm_create_with_vcpus(NR_VCPUS, guest_code, vcpus);
> [ ... ]
> > @@ -557,7 +555,7 @@ int main(int ac, char **av)
> > run_delay = get_run_delay();
> > pthread_create(&thread, NULL, do_steal_time, NULL);
> > pthread_getaffinity_np(thread, sizeof(cpuset), &cpuset);
> > - TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(0, &cpuset),
> > + TEST_ASSERT(CPU_COUNT(&cpuset) == 1 && CPU_ISSET(cpu, &cpuset),
>
> [Severity: Medium]
> Is there a race condition here if the worker thread exits before the parent
> reads its affinity?
>
> When pthread_create() spawns the worker thread, the child runs for a short
> duration and exits. If the parent thread is preempted right after creation,
> the child might finish its work and exit before pthread_getaffinity_np()
> executes in the parent.
>
> If the kernel task is already gone, pthread_getaffinity_np() will fail with
No, because the kernel task is kept alive until pthread_join(). As per the
pthread_create() manpage[*]:
Only when a terminated joinable thread has been joined are the last of its
resources released back to the system.
And by empirical testing, that includes the kernel task.
[*] https://man7.org/linux/man-pages/man3/pthread_create.3.html
> ESRCH. Because the explicit initialization of cpuset was removed earlier in
> main(), cpuset remains completely uninitialized.
>
> Could this cause CPU_COUNT() and CPU_ISSET() to evaluate garbage stack memory
> and trigger sporadic TEST_ASSERT failures? Should the return value of
> pthread_getaffinity_np() be checked, or should cpuset be initialized before
> the call?
The return value should be checked, but I'd rather handle that in a separate
cleanup by adding a wrapper in kvm_syscalls.h.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-07 16:15 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 15:07 [PATCH v2 0/2] KVM: selftest: Fix steal time w/ non-glibc builds Sean Christopherson
2026-07-07 15:07 ` [PATCH v2 1/2] KVM: selftests: Drop superfluous use of pthread_attr_setaffinity_np() Sean Christopherson
2026-07-07 15:21 ` sashiko-bot
2026-07-07 16:03 ` Sean Christopherson
2026-07-07 15:07 ` [PATCH v2 2/2] KVM: selftests: Randomize pCPU in steal time test Sean Christopherson
2026-07-07 15:29 ` sashiko-bot
2026-07-07 16:15 ` Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox