tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
Extension
.c
Size
9484 bytes
Lines
414
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (get_ucall(vcpu, &uc)) {
		case UCALL_SYNC:
			pthread_barrier_wait(&test_setup_barrier);
			continue;
		case UCALL_DONE:
			return NULL;
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
			break;
		default:
			TEST_FAIL("Unknown ucall: %lu", uc.cmd);
		}
	}

	return NULL;
}

static void report_stats(struct timespec delta)
{
	double nr_lpis;
	double time;

	nr_lpis = test_data.nr_devices * test_data.nr_event_ids * nr_iterations;

	time = delta.tv_sec;
	time += ((double)delta.tv_nsec) / NSEC_PER_SEC;

	pr_info("Rate: %.2f LPIs/sec\n", nr_lpis / time);
}

static void run_test(void)
{
	u32 nr_devices = test_data.nr_devices;
	u32 nr_vcpus = test_data.nr_cpus;
	pthread_t *lpi_threads = malloc(nr_devices * sizeof(pthread_t));
	pthread_t *vcpu_threads = malloc(nr_vcpus * sizeof(pthread_t));
	struct timespec start, delta;
	size_t i;

	TEST_ASSERT(lpi_threads && vcpu_threads, "Failed to allocate pthread arrays");

	pthread_barrier_init(&test_setup_barrier, NULL, nr_vcpus + nr_devices + 1);

	for (i = 0; i < nr_vcpus; i++)
		pthread_create(&vcpu_threads[i], NULL, vcpu_worker_thread, vcpus[i]);

	for (i = 0; i < nr_devices; i++)
		pthread_create(&lpi_threads[i], NULL, lpi_worker_thread, (void *)i);

	pthread_barrier_wait(&test_setup_barrier);

	clock_gettime(CLOCK_MONOTONIC, &start);

	for (i = 0; i < nr_devices; i++)
		pthread_join(lpi_threads[i], NULL);

	delta = timespec_elapsed(start);
	write_guest_global(vm, test_data.request_vcpus_stop, true);

	for (i = 0; i < nr_vcpus; i++)
		pthread_join(vcpu_threads[i], NULL);

	report_stats(delta);
}

static void setup_vm(void)
{
	int i;

	vcpus = malloc(test_data.nr_cpus * sizeof(struct kvm_vcpu *));
	TEST_ASSERT(vcpus, "Failed to allocate vCPU array");

	vm = vm_create_with_vcpus(test_data.nr_cpus, guest_code, vcpus);

	vm_init_descriptor_tables(vm);
	for (i = 0; i < test_data.nr_cpus; i++)
		vcpu_init_descriptor_tables(vcpus[i]);

	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, guest_irq_handler);

	setup_memslot();

	setup_gic();

	setup_test_data();
}

static void destroy_vm(void)
{
	close(its_fd);

Annotation

Implementation Notes