Message ID | 20230123190329.520285-2-bgardon@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | selftests: KVM: Add a test for eager page splitting | expand |
On Mon, Jan 23, 2023 at 11:03 AM Ben Gardon <bgardon@google.com> wrote: > > Move some helper functions from dirty_log_perf_test.c to the memstress > library so that they can be used in a future commit which tests page > splitting during dirty logging. > > Signed-off-by: Ben Gardon <bgardon@google.com> > --- > .../selftests/kvm/dirty_log_perf_test.c | 84 ++----------------- > .../testing/selftests/kvm/include/memstress.h | 8 ++ > tools/testing/selftests/kvm/lib/memstress.c | 72 ++++++++++++++++ > 3 files changed, 87 insertions(+), 77 deletions(-) > > diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c > index e9d6d1aecf89c..416719e205183 100644 > --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c > +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c > @@ -136,77 +136,6 @@ struct test_params { > bool random_access; > }; > > -static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) > -{ > - int i; > - > - for (i = 0; i < slots; i++) { > - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > - int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; > - > - vm_mem_region_set_flags(vm, slot, flags); > - } > -} > - > -static inline void enable_dirty_logging(struct kvm_vm *vm, int slots) > -{ > - toggle_dirty_logging(vm, slots, true); > -} > - > -static inline void disable_dirty_logging(struct kvm_vm *vm, int slots) > -{ > - toggle_dirty_logging(vm, slots, false); > -} > - > -static void get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) > -{ > - int i; > - > - for (i = 0; i < slots; i++) { > - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > - > - kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); > - } > -} > - > -static void clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], > - int slots, uint64_t pages_per_slot) > -{ > - int i; > - > - for (i = 0; i < slots; i++) { > - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > - > - kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); > - } > -} > - > -static unsigned long **alloc_bitmaps(int slots, uint64_t pages_per_slot) > -{ > - unsigned long **bitmaps; > - int i; > - > - bitmaps = malloc(slots * sizeof(bitmaps[0])); > - TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); > - > - for (i = 0; i < slots; i++) { > - bitmaps[i] = bitmap_zalloc(pages_per_slot); > - TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); > - } > - > - return bitmaps; > -} > - > -static void free_bitmaps(unsigned long *bitmaps[], int slots) > -{ > - int i; > - > - for (i = 0; i < slots; i++) > - free(bitmaps[i]); > - > - free(bitmaps); > -} > - > static void run_test(enum vm_guest_mode mode, void *arg) > { > struct test_params *p = arg; > @@ -236,7 +165,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) > host_num_pages = vm_num_host_pages(mode, guest_num_pages); > pages_per_slot = host_num_pages / p->slots; > > - bitmaps = alloc_bitmaps(p->slots, pages_per_slot); > + bitmaps = memstress_alloc_bitmaps(p->slots, pages_per_slot); > > if (dirty_log_manual_caps) > vm_enable_cap(vm, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, > @@ -277,7 +206,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) > > /* Enable dirty logging */ > clock_gettime(CLOCK_MONOTONIC, &start); > - enable_dirty_logging(vm, p->slots); > + memstress_enable_dirty_logging(vm, p->slots); > ts_diff = timespec_elapsed(start); > pr_info("Enabling dirty logging time: %ld.%.9lds\n\n", > ts_diff.tv_sec, ts_diff.tv_nsec); > @@ -306,7 +235,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) > iteration, ts_diff.tv_sec, ts_diff.tv_nsec); > > clock_gettime(CLOCK_MONOTONIC, &start); > - get_dirty_log(vm, bitmaps, p->slots); > + memstress_get_dirty_log(vm, bitmaps, p->slots); > ts_diff = timespec_elapsed(start); > get_dirty_log_total = timespec_add(get_dirty_log_total, > ts_diff); > @@ -315,7 +244,8 @@ static void run_test(enum vm_guest_mode mode, void *arg) > > if (dirty_log_manual_caps) { > clock_gettime(CLOCK_MONOTONIC, &start); > - clear_dirty_log(vm, bitmaps, p->slots, pages_per_slot); > + memstress_clear_dirty_log(vm, bitmaps, p->slots, > + pages_per_slot); > ts_diff = timespec_elapsed(start); > clear_dirty_log_total = timespec_add(clear_dirty_log_total, > ts_diff); > @@ -334,7 +264,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) > > /* Disable dirty logging */ > clock_gettime(CLOCK_MONOTONIC, &start); > - disable_dirty_logging(vm, p->slots); > + memstress_disable_dirty_logging(vm, p->slots); > ts_diff = timespec_elapsed(start); > pr_info("Disabling dirty logging time: %ld.%.9lds\n", > ts_diff.tv_sec, ts_diff.tv_nsec); > @@ -359,7 +289,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) > clear_dirty_log_total.tv_nsec, avg.tv_sec, avg.tv_nsec); > } > > - free_bitmaps(bitmaps, p->slots); > + memstress_free_bitmaps(bitmaps, p->slots); > arch_cleanup_vm(vm); > memstress_destroy_vm(vm); > } > diff --git a/tools/testing/selftests/kvm/include/memstress.h b/tools/testing/selftests/kvm/include/memstress.h > index 72e3e358ef7bd..ce4e603050eaa 100644 > --- a/tools/testing/selftests/kvm/include/memstress.h > +++ b/tools/testing/selftests/kvm/include/memstress.h > @@ -72,4 +72,12 @@ void memstress_guest_code(uint32_t vcpu_id); > uint64_t memstress_nested_pages(int nr_vcpus); > void memstress_setup_nested(struct kvm_vm *vm, int nr_vcpus, struct kvm_vcpu *vcpus[]); > > +void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots); > +void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots); > +void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots); > +void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], > + int slots, uint64_t pages_per_slot); > +unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot); > +void memstress_free_bitmaps(unsigned long *bitmaps[], int slots); > + > #endif /* SELFTEST_KVM_MEMSTRESS_H */ > diff --git a/tools/testing/selftests/kvm/lib/memstress.c b/tools/testing/selftests/kvm/lib/memstress.c > index 5f1d3173c238c..3632956c6bcf5 100644 > --- a/tools/testing/selftests/kvm/lib/memstress.c > +++ b/tools/testing/selftests/kvm/lib/memstress.c > @@ -5,6 +5,7 @@ > #define _GNU_SOURCE > > #include <inttypes.h> > +#include <linux/bitmap.h> > > #include "kvm_util.h" > #include "memstress.h" > @@ -320,3 +321,74 @@ void memstress_join_vcpu_threads(int nr_vcpus) > for (i = 0; i < nr_vcpus; i++) > pthread_join(vcpu_threads[i].thread, NULL); > } > + > +static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) > +{ > + int i; > + > + for (i = 0; i < slots; i++) { > + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > + int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; > + > + vm_mem_region_set_flags(vm, slot, flags); > + } > +} > + > +void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots) > +{ > + toggle_dirty_logging(vm, slots, true); > +} > + > +void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots) > +{ > + toggle_dirty_logging(vm, slots, false); > +} Very simple functions, maybe just make it inline in the memstress header. > + > +void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) > +{ > + int i; > + > + for (i = 0; i < slots; i++) { > + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > + > + kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); > + } > +} > + > +void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], > + int slots, uint64_t pages_per_slot) > +{ > + int i; > + > + for (i = 0; i < slots; i++) { > + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; > + > + kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); > + } > +} > + > +unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot) > +{ > + unsigned long **bitmaps; > + int i; > + > + bitmaps = malloc(slots * sizeof(bitmaps[0])); > + TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); > + > + for (i = 0; i < slots; i++) { > + bitmaps[i] = bitmap_zalloc(pages_per_slot); > + TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); > + } > + > + return bitmaps; > +} > + > +void memstress_free_bitmaps(unsigned long *bitmaps[], int slots) > +{ > + int i; > + > + for (i = 0; i < slots; i++) > + free(bitmaps[i]); > + > + free(bitmaps); > +} > -- > 2.39.1.405.gd4c25cc71f-goog > Other than the inline suggestion, which is optional. Reviewed-by: Vipin Sharma <vipinsh@google.com>
diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c index e9d6d1aecf89c..416719e205183 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -136,77 +136,6 @@ struct test_params { bool random_access; }; -static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) -{ - int i; - - for (i = 0; i < slots; i++) { - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; - int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; - - vm_mem_region_set_flags(vm, slot, flags); - } -} - -static inline void enable_dirty_logging(struct kvm_vm *vm, int slots) -{ - toggle_dirty_logging(vm, slots, true); -} - -static inline void disable_dirty_logging(struct kvm_vm *vm, int slots) -{ - toggle_dirty_logging(vm, slots, false); -} - -static void get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) -{ - int i; - - for (i = 0; i < slots; i++) { - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; - - kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); - } -} - -static void clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], - int slots, uint64_t pages_per_slot) -{ - int i; - - for (i = 0; i < slots; i++) { - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; - - kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); - } -} - -static unsigned long **alloc_bitmaps(int slots, uint64_t pages_per_slot) -{ - unsigned long **bitmaps; - int i; - - bitmaps = malloc(slots * sizeof(bitmaps[0])); - TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); - - for (i = 0; i < slots; i++) { - bitmaps[i] = bitmap_zalloc(pages_per_slot); - TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); - } - - return bitmaps; -} - -static void free_bitmaps(unsigned long *bitmaps[], int slots) -{ - int i; - - for (i = 0; i < slots; i++) - free(bitmaps[i]); - - free(bitmaps); -} - static void run_test(enum vm_guest_mode mode, void *arg) { struct test_params *p = arg; @@ -236,7 +165,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) host_num_pages = vm_num_host_pages(mode, guest_num_pages); pages_per_slot = host_num_pages / p->slots; - bitmaps = alloc_bitmaps(p->slots, pages_per_slot); + bitmaps = memstress_alloc_bitmaps(p->slots, pages_per_slot); if (dirty_log_manual_caps) vm_enable_cap(vm, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, @@ -277,7 +206,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) /* Enable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); - enable_dirty_logging(vm, p->slots); + memstress_enable_dirty_logging(vm, p->slots); ts_diff = timespec_elapsed(start); pr_info("Enabling dirty logging time: %ld.%.9lds\n\n", ts_diff.tv_sec, ts_diff.tv_nsec); @@ -306,7 +235,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) iteration, ts_diff.tv_sec, ts_diff.tv_nsec); clock_gettime(CLOCK_MONOTONIC, &start); - get_dirty_log(vm, bitmaps, p->slots); + memstress_get_dirty_log(vm, bitmaps, p->slots); ts_diff = timespec_elapsed(start); get_dirty_log_total = timespec_add(get_dirty_log_total, ts_diff); @@ -315,7 +244,8 @@ static void run_test(enum vm_guest_mode mode, void *arg) if (dirty_log_manual_caps) { clock_gettime(CLOCK_MONOTONIC, &start); - clear_dirty_log(vm, bitmaps, p->slots, pages_per_slot); + memstress_clear_dirty_log(vm, bitmaps, p->slots, + pages_per_slot); ts_diff = timespec_elapsed(start); clear_dirty_log_total = timespec_add(clear_dirty_log_total, ts_diff); @@ -334,7 +264,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) /* Disable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); - disable_dirty_logging(vm, p->slots); + memstress_disable_dirty_logging(vm, p->slots); ts_diff = timespec_elapsed(start); pr_info("Disabling dirty logging time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); @@ -359,7 +289,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) clear_dirty_log_total.tv_nsec, avg.tv_sec, avg.tv_nsec); } - free_bitmaps(bitmaps, p->slots); + memstress_free_bitmaps(bitmaps, p->slots); arch_cleanup_vm(vm); memstress_destroy_vm(vm); } diff --git a/tools/testing/selftests/kvm/include/memstress.h b/tools/testing/selftests/kvm/include/memstress.h index 72e3e358ef7bd..ce4e603050eaa 100644 --- a/tools/testing/selftests/kvm/include/memstress.h +++ b/tools/testing/selftests/kvm/include/memstress.h @@ -72,4 +72,12 @@ void memstress_guest_code(uint32_t vcpu_id); uint64_t memstress_nested_pages(int nr_vcpus); void memstress_setup_nested(struct kvm_vm *vm, int nr_vcpus, struct kvm_vcpu *vcpus[]); +void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots); +void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots); +void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots); +void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], + int slots, uint64_t pages_per_slot); +unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot); +void memstress_free_bitmaps(unsigned long *bitmaps[], int slots); + #endif /* SELFTEST_KVM_MEMSTRESS_H */ diff --git a/tools/testing/selftests/kvm/lib/memstress.c b/tools/testing/selftests/kvm/lib/memstress.c index 5f1d3173c238c..3632956c6bcf5 100644 --- a/tools/testing/selftests/kvm/lib/memstress.c +++ b/tools/testing/selftests/kvm/lib/memstress.c @@ -5,6 +5,7 @@ #define _GNU_SOURCE #include <inttypes.h> +#include <linux/bitmap.h> #include "kvm_util.h" #include "memstress.h" @@ -320,3 +321,74 @@ void memstress_join_vcpu_threads(int nr_vcpus) for (i = 0; i < nr_vcpus; i++) pthread_join(vcpu_threads[i].thread, NULL); } + +static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) +{ + int i; + + for (i = 0; i < slots; i++) { + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; + int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; + + vm_mem_region_set_flags(vm, slot, flags); + } +} + +void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots) +{ + toggle_dirty_logging(vm, slots, true); +} + +void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots) +{ + toggle_dirty_logging(vm, slots, false); +} + +void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) +{ + int i; + + for (i = 0; i < slots; i++) { + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; + + kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); + } +} + +void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], + int slots, uint64_t pages_per_slot) +{ + int i; + + for (i = 0; i < slots; i++) { + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; + + kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); + } +} + +unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot) +{ + unsigned long **bitmaps; + int i; + + bitmaps = malloc(slots * sizeof(bitmaps[0])); + TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); + + for (i = 0; i < slots; i++) { + bitmaps[i] = bitmap_zalloc(pages_per_slot); + TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); + } + + return bitmaps; +} + +void memstress_free_bitmaps(unsigned long *bitmaps[], int slots) +{ + int i; + + for (i = 0; i < slots; i++) + free(bitmaps[i]); + + free(bitmaps); +}
Move some helper functions from dirty_log_perf_test.c to the memstress library so that they can be used in a future commit which tests page splitting during dirty logging. Signed-off-by: Ben Gardon <bgardon@google.com> --- .../selftests/kvm/dirty_log_perf_test.c | 84 ++----------------- .../testing/selftests/kvm/include/memstress.h | 8 ++ tools/testing/selftests/kvm/lib/memstress.c | 72 ++++++++++++++++ 3 files changed, 87 insertions(+), 77 deletions(-)