tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/vfio/vfio_pci_device_init_perf_test.c
Extension
.c
Size
4009 bytes
Lines
169
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

struct thread_args {
	struct iommu *iommu;
	int device_index;
	struct timespec start;
	struct timespec end;
	pthread_barrier_t *barrier;
};

FIXTURE(vfio_pci_device_init_perf_test) {
	pthread_t *threads;
	pthread_barrier_t barrier;
	struct thread_args *thread_args;
	struct iommu *iommu;
};

FIXTURE_VARIANT(vfio_pci_device_init_perf_test) {
	const char *iommu_mode;
};

#define FIXTURE_VARIANT_ADD_IOMMU_MODE(_iommu_mode)			\
FIXTURE_VARIANT_ADD(vfio_pci_device_init_perf_test, _iommu_mode) {	\
	.iommu_mode = #_iommu_mode,					\
}

FIXTURE_VARIANT_ADD_ALL_IOMMU_MODES();

FIXTURE_SETUP(vfio_pci_device_init_perf_test)
{
	int i;

	self->iommu = iommu_init(variant->iommu_mode);
	self->threads = calloc(nr_devices, sizeof(self->threads[0]));
	self->thread_args = calloc(nr_devices, sizeof(self->thread_args[0]));

	pthread_barrier_init(&self->barrier, NULL, nr_devices);

	for (i = 0; i < nr_devices; i++) {
		self->thread_args[i].iommu = self->iommu;
		self->thread_args[i].barrier = &self->barrier;
		self->thread_args[i].device_index = i;
	}
}

FIXTURE_TEARDOWN(vfio_pci_device_init_perf_test)
{
	iommu_cleanup(self->iommu);
	free(self->threads);
	free(self->thread_args);
}

static s64 to_ns(struct timespec ts)
{
	return (s64)ts.tv_nsec + NSEC_PER_SEC * (s64)ts.tv_sec;
}

static struct timespec to_timespec(s64 ns)
{
	struct timespec ts = {
		.tv_nsec = ns % NSEC_PER_SEC,
		.tv_sec = ns / NSEC_PER_SEC,
	};

	return ts;
}

static struct timespec timespec_sub(struct timespec a, struct timespec b)
{
	return to_timespec(to_ns(a) - to_ns(b));
}

static struct timespec timespec_min(struct timespec a, struct timespec b)
{
	return to_ns(a) < to_ns(b) ? a : b;
}

static struct timespec timespec_max(struct timespec a, struct timespec b)
{
	return to_ns(a) > to_ns(b) ? a : b;
}

static void *thread_main(void *__args)
{
	struct thread_args *args = __args;
	struct vfio_pci_device *device;

	pthread_barrier_wait(args->barrier);

	clock_gettime(CLOCK_MONOTONIC, &args->start);
	device = vfio_pci_device_init(device_bdfs[args->device_index], args->iommu);
	clock_gettime(CLOCK_MONOTONIC, &args->end);

Annotation

Implementation Notes