mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 10:02:02 +02:00
KVM: selftests: Set threads CPU affinity before doing work in hardware disable test
Affine worker threads to their target pCPU set *before* doing any work in the hardware disable test. When running a preemptible kernel on a NUMA system with a large number of CPUs (100+ of CPUs), waiting to set the affinity of the grandchildren until after the grandchild is fully spun up results in total test runtimes of over a minute, presumably due to cross-node NUMA penalties and scheduler lock contention. E.g. from the perspective of the caller, when waiting to affine the tasks, pthread_create() takes ~100x longer. Link: https://patch.msgid.link/20260731195612.2697986-3-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
f766bf3d0a
commit
2887da61c4
|
|
@ -21,6 +21,7 @@
|
|||
#define FORK_NUM (1ULL << 9)
|
||||
#define DELAY_US_MAX 2000
|
||||
|
||||
static cpu_set_t threads_cpu_set;
|
||||
sem_t *sem;
|
||||
|
||||
static void guest_code(void)
|
||||
|
|
@ -35,6 +36,8 @@ static void *run_vcpu(void *arg)
|
|||
struct kvm_vcpu *vcpu = arg;
|
||||
struct kvm_run *run = vcpu->run;
|
||||
|
||||
kvm_sched_setaffinity(0, sizeof(cpu_set_t), &threads_cpu_set);
|
||||
|
||||
vcpu_run(vcpu);
|
||||
|
||||
TEST_ASSERT(false, "%s: exited with reason %d: %s",
|
||||
|
|
@ -47,6 +50,8 @@ static void *sleeping_thread(void *arg)
|
|||
{
|
||||
int fd;
|
||||
|
||||
kvm_sched_setaffinity(0, sizeof(cpu_set_t), &threads_cpu_set);
|
||||
|
||||
while (true) {
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
close(fd);
|
||||
|
|
@ -64,14 +69,6 @@ static inline void check_create_thread(pthread_t *thread, pthread_attr_t *attr,
|
|||
TEST_ASSERT(r == 0, "%s: failed to create thread", __func__);
|
||||
}
|
||||
|
||||
static inline void check_set_affinity(pthread_t thread, cpu_set_t *cpu_set)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = pthread_setaffinity_np(thread, sizeof(cpu_set_t), cpu_set);
|
||||
TEST_ASSERT(r == 0, "%s: failed set affinity", __func__);
|
||||
}
|
||||
|
||||
static inline void check_join(pthread_t thread, void **retval)
|
||||
{
|
||||
int r;
|
||||
|
|
@ -84,16 +81,11 @@ static void run_test(u32 run)
|
|||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct kvm_vm *vm;
|
||||
cpu_set_t cpu_set;
|
||||
pthread_t threads[VCPU_NUM];
|
||||
pthread_t throw_away;
|
||||
void *b;
|
||||
u32 i, j;
|
||||
|
||||
CPU_ZERO(&cpu_set);
|
||||
for (i = 0; i < VCPU_NUM; i++)
|
||||
CPU_SET(i, &cpu_set);
|
||||
|
||||
vm = vm_create(VCPU_NUM);
|
||||
|
||||
pr_debug("%s: [%d] start vcpus\n", __func__, run);
|
||||
|
|
@ -101,12 +93,10 @@ static void run_test(u32 run)
|
|||
vcpu = vm_vcpu_add(vm, i, guest_code);
|
||||
|
||||
check_create_thread(&threads[i], NULL, run_vcpu, vcpu);
|
||||
check_set_affinity(threads[i], &cpu_set);
|
||||
|
||||
for (j = 0; j < SLEEPING_THREAD_NUM; ++j) {
|
||||
check_create_thread(&throw_away, NULL, sleeping_thread,
|
||||
(void *)NULL);
|
||||
check_set_affinity(throw_away, &cpu_set);
|
||||
}
|
||||
}
|
||||
pr_debug("%s: [%d] all threads launched\n", __func__, run);
|
||||
|
|
@ -153,6 +143,9 @@ int main(int argc, char **argv)
|
|||
int s, r;
|
||||
pid_t pid;
|
||||
|
||||
for (i = 0; i < VCPU_NUM; i++)
|
||||
CPU_SET(i, &threads_cpu_set);
|
||||
|
||||
sem = sem_open("vm_sem", O_CREAT | O_EXCL, 0644, 0);
|
||||
sem_unlink("vm_sem");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user