From 841e94898a55ff79af9d20a08205aa80808bd2a8 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Fri, 21 May 2021 23:43:16 +0200 Subject: [PATCH] Flag test --- .../testing/selftests/kvm/memslot_perf_test.c | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/kvm/memslot_perf_test.c b/tools/testing/selftests/kvm/memslot_perf_test.c index 4ae0e5ec0f7401..47d3000db3ca23 100644 --- a/tools/testing/selftests/kvm/memslot_perf_test.c +++ b/tools/testing/selftests/kvm/memslot_perf_test.c @@ -233,7 +233,7 @@ static struct vm_data *alloc_vm(void) } static bool prepare_vm(struct vm_data *data, int nslots, uint64_t *maxslots, - void *guest_code, uint64_t mempages, + void *guest_code, uint64_t mempages, bool mempages_per_memslot, struct timespec *slot_runtime) { uint32_t max_mem_slots; @@ -252,22 +252,31 @@ static bool prepare_vm(struct vm_data *data, int nslots, uint64_t *maxslots, max_mem_slots = min(max_mem_slots, (uint32_t)nslots); pr_info_v("Allowed number of memory slots: %"PRIu32"\n", max_mem_slots); - TEST_ASSERT(mempages > 1, + TEST_ASSERT(mempages > (mempages_per_memslot ? 0 : 1), "Can't test without any memory"); - data->npages = mempages; data->nslots = max_mem_slots - 1; - data->pages_per_slot = mempages / data->nslots; - if (!data->pages_per_slot) { - *maxslots = mempages + 1; - return false; + if (!mempages_per_memslot) { + data->npages = mempages; + data->pages_per_slot = mempages / data->nslots; + if (!data->pages_per_slot) { + *maxslots = mempages + 1; + return false; + } + } else { + data->pages_per_slot = mempages; + data->npages = mempages * data->nslots; + if (data->nslots > UINT64_MAX / mempages) { + *maxslots = UINT64_MAX / mempages + 1; + return false; + } } - rempages = mempages % data->nslots; + rempages = data->npages % data->nslots; data->hva_slots = malloc(sizeof(*data->hva_slots) * data->nslots); TEST_ASSERT(data->hva_slots, "malloc() fail"); - data->vm = vm_create_default(VCPU_ID, mempages, guest_code); + data->vm = vm_create_default(VCPU_ID, data->npages, guest_code); pr_info_v("Adding slots 1..%i, each slot with %"PRIu64" pages + %"PRIu64" extra pages last\n", max_mem_slots - 1, data->pages_per_slot, rempages); @@ -306,7 +315,7 @@ static bool prepare_vm(struct vm_data *data, int nslots, uint64_t *maxslots, guest_addr += npages * 4096; } - virt_map(data->vm, MEM_GPA, MEM_GPA, mempages, 0); + virt_map(data->vm, MEM_GPA, MEM_GPA, data->npages, 0); sync = (typeof(sync))vm_gpa2hva(data, MEM_SYNC_GPA, NULL); atomic_init(&sync->start_flag, false); @@ -699,6 +708,14 @@ static void test_memslot_unmap_loop_chunked(struct vm_data *data, test_memslot_unmap_loop_common(data, sync, MEM_TEST_UNMAP_CHUNK_PAGES); } +static void test_memslot_toggle_dirty_flag_loop(struct vm_data *data, + struct sync_area *sync) +{ + vm_mem_region_set_flags(data->vm, data->nslots - 1 + 1, + KVM_MEM_LOG_DIRTY_PAGES); + vm_mem_region_set_flags(data->vm, data->nslots - 1 + 1, 0); +} + static void test_memslot_rw_loop(struct vm_data *data, struct sync_area *sync) { uint64_t gptr; @@ -726,6 +743,7 @@ static void test_memslot_rw_loop(struct vm_data *data, struct sync_area *sync) struct test_data { const char *name; uint64_t mem_size; + bool mem_size_per_memslot; void (*guest_code)(void); bool (*prepare)(struct vm_data *data, struct sync_area *sync, uint64_t *maxslots); @@ -747,7 +765,7 @@ static bool test_execute(int nslots, uint64_t *maxslots, data = alloc_vm(); if (!prepare_vm(data, nslots, maxslots, tdata->guest_code, - mem_size, slot_runtime)) { + mem_size, tdata->mem_size_per_memslot, slot_runtime)) { ret = false; goto exit_free; } @@ -760,10 +778,15 @@ static bool test_execute(int nslots, uint64_t *maxslots, goto exit_free; } - launch_vm(data); + if (tdata->guest_code) + launch_vm(data); + else + pr_info_v("Starting a host-only test\n"); clock_gettime(CLOCK_MONOTONIC, &tstart); - let_guest_run(sync); + + if (tdata->guest_code) + let_guest_run(sync); while (1) { *guest_runtime = timespec_elapsed(tstart); @@ -775,8 +798,10 @@ static bool test_execute(int nslots, uint64_t *maxslots, (*nloops)++; } - make_guest_exit(sync); - wait_guest_exit(data); + if (tdata->guest_code) { + make_guest_exit(sync); + wait_guest_exit(data); + } exit_free: free_vm(data); @@ -815,6 +840,12 @@ static const struct test_data tests[] = { .prepare = test_memslot_move_prepare_inactive, .loop = test_memslot_move_loop, }, + { + .name = "toggle dirty flag", + .mem_size = 1, + .mem_size_per_memslot = true, + .loop = test_memslot_toggle_dirty_flag_loop, + }, { .name = "RW", .guest_code = guest_code_test_memslot_rw, @@ -974,7 +1005,7 @@ static bool test_loop(const struct test_data *data, * Only rank the slot setup time for tests using the whole test memory * area so they are comparable */ - if (!data->mem_size && + if (!data->mem_size && !data->mem_size_per_memslot && (!rbestslottime->slottimens || result.slottimens < rbestslottime->slottimens)) *rbestslottime = result;