Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: selftests: Move dirty logging functions to memstress.(c|h)

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.

Reviewed-by: Vipin Sharma <vipinsh@google.com>
Signed-off-by: Ben Gardon <bgardon@google.com>
Link: https://lore.kernel.org/r/20230131181820.179033-2-bgardon@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>

authored by

Ben Gardon and committed by
Sean Christopherson
de10b798 07b4b2f4

+87 -77
+7 -77
tools/testing/selftests/kvm/dirty_log_perf_test.c
··· 136 136 bool random_access; 137 137 }; 138 138 139 - static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) 140 - { 141 - int i; 142 - 143 - for (i = 0; i < slots; i++) { 144 - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 145 - int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; 146 - 147 - vm_mem_region_set_flags(vm, slot, flags); 148 - } 149 - } 150 - 151 - static inline void enable_dirty_logging(struct kvm_vm *vm, int slots) 152 - { 153 - toggle_dirty_logging(vm, slots, true); 154 - } 155 - 156 - static inline void disable_dirty_logging(struct kvm_vm *vm, int slots) 157 - { 158 - toggle_dirty_logging(vm, slots, false); 159 - } 160 - 161 - static void get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) 162 - { 163 - int i; 164 - 165 - for (i = 0; i < slots; i++) { 166 - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 167 - 168 - kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); 169 - } 170 - } 171 - 172 - static void clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], 173 - int slots, uint64_t pages_per_slot) 174 - { 175 - int i; 176 - 177 - for (i = 0; i < slots; i++) { 178 - int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 179 - 180 - kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); 181 - } 182 - } 183 - 184 - static unsigned long **alloc_bitmaps(int slots, uint64_t pages_per_slot) 185 - { 186 - unsigned long **bitmaps; 187 - int i; 188 - 189 - bitmaps = malloc(slots * sizeof(bitmaps[0])); 190 - TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); 191 - 192 - for (i = 0; i < slots; i++) { 193 - bitmaps[i] = bitmap_zalloc(pages_per_slot); 194 - TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); 195 - } 196 - 197 - return bitmaps; 198 - } 199 - 200 - static void free_bitmaps(unsigned long *bitmaps[], int slots) 201 - { 202 - int i; 203 - 204 - for (i = 0; i < slots; i++) 205 - free(bitmaps[i]); 206 - 207 - free(bitmaps); 208 - } 209 - 210 139 static void run_test(enum vm_guest_mode mode, void *arg) 211 140 { 212 141 struct test_params *p = arg; ··· 165 236 host_num_pages = vm_num_host_pages(mode, guest_num_pages); 166 237 pages_per_slot = host_num_pages / p->slots; 167 238 168 - bitmaps = alloc_bitmaps(p->slots, pages_per_slot); 239 + bitmaps = memstress_alloc_bitmaps(p->slots, pages_per_slot); 169 240 170 241 if (dirty_log_manual_caps) 171 242 vm_enable_cap(vm, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, ··· 206 277 207 278 /* Enable dirty logging */ 208 279 clock_gettime(CLOCK_MONOTONIC, &start); 209 - enable_dirty_logging(vm, p->slots); 280 + memstress_enable_dirty_logging(vm, p->slots); 210 281 ts_diff = timespec_elapsed(start); 211 282 pr_info("Enabling dirty logging time: %ld.%.9lds\n\n", 212 283 ts_diff.tv_sec, ts_diff.tv_nsec); ··· 235 306 iteration, ts_diff.tv_sec, ts_diff.tv_nsec); 236 307 237 308 clock_gettime(CLOCK_MONOTONIC, &start); 238 - get_dirty_log(vm, bitmaps, p->slots); 309 + memstress_get_dirty_log(vm, bitmaps, p->slots); 239 310 ts_diff = timespec_elapsed(start); 240 311 get_dirty_log_total = timespec_add(get_dirty_log_total, 241 312 ts_diff); ··· 244 315 245 316 if (dirty_log_manual_caps) { 246 317 clock_gettime(CLOCK_MONOTONIC, &start); 247 - clear_dirty_log(vm, bitmaps, p->slots, pages_per_slot); 318 + memstress_clear_dirty_log(vm, bitmaps, p->slots, 319 + pages_per_slot); 248 320 ts_diff = timespec_elapsed(start); 249 321 clear_dirty_log_total = timespec_add(clear_dirty_log_total, 250 322 ts_diff); ··· 264 334 265 335 /* Disable dirty logging */ 266 336 clock_gettime(CLOCK_MONOTONIC, &start); 267 - disable_dirty_logging(vm, p->slots); 337 + memstress_disable_dirty_logging(vm, p->slots); 268 338 ts_diff = timespec_elapsed(start); 269 339 pr_info("Disabling dirty logging time: %ld.%.9lds\n", 270 340 ts_diff.tv_sec, ts_diff.tv_nsec); ··· 289 359 clear_dirty_log_total.tv_nsec, avg.tv_sec, avg.tv_nsec); 290 360 } 291 361 292 - free_bitmaps(bitmaps, p->slots); 362 + memstress_free_bitmaps(bitmaps, p->slots); 293 363 arch_cleanup_vm(vm); 294 364 memstress_destroy_vm(vm); 295 365 }
+8
tools/testing/selftests/kvm/include/memstress.h
··· 72 72 uint64_t memstress_nested_pages(int nr_vcpus); 73 73 void memstress_setup_nested(struct kvm_vm *vm, int nr_vcpus, struct kvm_vcpu *vcpus[]); 74 74 75 + void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots); 76 + void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots); 77 + void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots); 78 + void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], 79 + int slots, uint64_t pages_per_slot); 80 + unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot); 81 + void memstress_free_bitmaps(unsigned long *bitmaps[], int slots); 82 + 75 83 #endif /* SELFTEST_KVM_MEMSTRESS_H */
+72
tools/testing/selftests/kvm/lib/memstress.c
··· 5 5 #define _GNU_SOURCE 6 6 7 7 #include <inttypes.h> 8 + #include <linux/bitmap.h> 8 9 9 10 #include "kvm_util.h" 10 11 #include "memstress.h" ··· 323 322 324 323 for (i = 0; i < nr_vcpus; i++) 325 324 pthread_join(vcpu_threads[i].thread, NULL); 325 + } 326 + 327 + static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) 328 + { 329 + int i; 330 + 331 + for (i = 0; i < slots; i++) { 332 + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 333 + int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; 334 + 335 + vm_mem_region_set_flags(vm, slot, flags); 336 + } 337 + } 338 + 339 + void memstress_enable_dirty_logging(struct kvm_vm *vm, int slots) 340 + { 341 + toggle_dirty_logging(vm, slots, true); 342 + } 343 + 344 + void memstress_disable_dirty_logging(struct kvm_vm *vm, int slots) 345 + { 346 + toggle_dirty_logging(vm, slots, false); 347 + } 348 + 349 + void memstress_get_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], int slots) 350 + { 351 + int i; 352 + 353 + for (i = 0; i < slots; i++) { 354 + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 355 + 356 + kvm_vm_get_dirty_log(vm, slot, bitmaps[i]); 357 + } 358 + } 359 + 360 + void memstress_clear_dirty_log(struct kvm_vm *vm, unsigned long *bitmaps[], 361 + int slots, uint64_t pages_per_slot) 362 + { 363 + int i; 364 + 365 + for (i = 0; i < slots; i++) { 366 + int slot = MEMSTRESS_MEM_SLOT_INDEX + i; 367 + 368 + kvm_vm_clear_dirty_log(vm, slot, bitmaps[i], 0, pages_per_slot); 369 + } 370 + } 371 + 372 + unsigned long **memstress_alloc_bitmaps(int slots, uint64_t pages_per_slot) 373 + { 374 + unsigned long **bitmaps; 375 + int i; 376 + 377 + bitmaps = malloc(slots * sizeof(bitmaps[0])); 378 + TEST_ASSERT(bitmaps, "Failed to allocate bitmaps array."); 379 + 380 + for (i = 0; i < slots; i++) { 381 + bitmaps[i] = bitmap_zalloc(pages_per_slot); 382 + TEST_ASSERT(bitmaps[i], "Failed to allocate slot bitmap."); 383 + } 384 + 385 + return bitmaps; 386 + } 387 + 388 + void memstress_free_bitmaps(unsigned long *bitmaps[], int slots) 389 + { 390 + int i; 391 + 392 + for (i = 0; i < slots; i++) 393 + free(bitmaps[i]); 394 + 395 + free(bitmaps); 326 396 }