tools/testing/selftests/kvm/dirty_log_test.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/dirty_log_test.c
Extension
.c
Size
27081 bytes
Lines
921
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 log_mode {
	const char *name;
	/* Return true if this mode is supported, otherwise false */
	bool (*supported)(void);
	/* Hook when the vm creation is done (before vcpu creation) */
	void (*create_vm_done)(struct kvm_vm *vm);
	/* Hook to collect the dirty pages into the bitmap provided */
	void (*collect_dirty_pages) (struct kvm_vcpu *vcpu, int slot,
				     void *bitmap, u32 num_pages,
				     u32 *ring_buf_idx);
	/* Hook to call when after each vcpu run */
	void (*after_vcpu_run)(struct kvm_vcpu *vcpu);
} log_modes[LOG_MODE_NUM] = {
	{
		.name = "dirty-log",
		.collect_dirty_pages = dirty_log_collect_dirty_pages,
		.after_vcpu_run = default_after_vcpu_run,
	},
	{
		.name = "clear-log",
		.supported = clear_log_supported,
		.create_vm_done = clear_log_create_vm_done,
		.collect_dirty_pages = clear_log_collect_dirty_pages,
		.after_vcpu_run = default_after_vcpu_run,
	},
	{
		.name = "dirty-ring",
		.supported = dirty_ring_supported,
		.create_vm_done = dirty_ring_create_vm_done,
		.collect_dirty_pages = dirty_ring_collect_dirty_pages,
		.after_vcpu_run = dirty_ring_after_vcpu_run,
	},
};

static void log_modes_dump(void)
{
	int i;

	printf("all");
	for (i = 0; i < LOG_MODE_NUM; i++)
		printf(", %s", log_modes[i].name);
	printf("\n");
}

static bool log_mode_supported(void)
{
	struct log_mode *mode = &log_modes[host_log_mode];

	if (mode->supported)
		return mode->supported();

	return true;
}

static void log_mode_create_vm_done(struct kvm_vm *vm)
{
	struct log_mode *mode = &log_modes[host_log_mode];

	if (mode->create_vm_done)
		mode->create_vm_done(vm);
}

static void log_mode_collect_dirty_pages(struct kvm_vcpu *vcpu, int slot,
					 void *bitmap, u32 num_pages,
					 u32 *ring_buf_idx)
{
	struct log_mode *mode = &log_modes[host_log_mode];

	TEST_ASSERT(mode->collect_dirty_pages != NULL,
		    "collect_dirty_pages() is required for any log mode!");
	mode->collect_dirty_pages(vcpu, slot, bitmap, num_pages, ring_buf_idx);
}

static void log_mode_after_vcpu_run(struct kvm_vcpu *vcpu)
{
	struct log_mode *mode = &log_modes[host_log_mode];

	if (mode->after_vcpu_run)
		mode->after_vcpu_run(vcpu);
}

static void *vcpu_worker(void *data)
{
	struct kvm_vcpu *vcpu = data;

	sem_wait(&sem_vcpu_cont);

	while (!READ_ONCE(host_quit)) {
		/* Let the guest dirty the random pages */
		vcpu_run(vcpu);

Annotation

Implementation Notes