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

KVM: selftests: Allow specify physical cpu list in demand paging test

Mimic the dirty log test and allow the user to pin demand paging test
tasks to physical CPUs.

Put the help message into a general helper as suggested by Sean.

Signed-off-by: Peter Xu <peterx@redhat.com>
[sean: rebase, tweak arg ordering, add "print" to helper, print program name]
Link: https://lore.kernel.org/r/20230607001226.1398889-1-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>

authored by

Peter Xu and committed by
Sean Christopherson
d4ec586c dfa78a20

+32 -13
+13 -2
tools/testing/selftests/kvm/demand_paging_test.c
··· 208 208 { 209 209 puts(""); 210 210 printf("usage: %s [-h] [-m vm_mode] [-u uffd_mode] [-d uffd_delay_usec]\n" 211 - " [-b memory] [-s type] [-v vcpus] [-o]\n", name); 211 + " [-b memory] [-s type] [-v vcpus] [-c cpu_list] [-o]\n", name); 212 212 guest_modes_help(); 213 213 printf(" -u: use userfaultfd to handle vCPU page faults. Mode is a\n" 214 214 " UFFD registration mode: 'MISSING' or 'MINOR'.\n"); 215 + kvm_print_vcpu_pinning_help(); 215 216 printf(" -d: add a delay in usec to the User Fault\n" 216 217 " FD handler to simulate demand paging\n" 217 218 " overheads. Ignored without -u.\n"); ··· 230 229 int main(int argc, char *argv[]) 231 230 { 232 231 int max_vcpus = kvm_check_cap(KVM_CAP_MAX_VCPUS); 232 + const char *cpulist = NULL; 233 233 struct test_params p = { 234 234 .src_type = DEFAULT_VM_MEM_SRC, 235 235 .partition_vcpu_memory_access = true, ··· 239 237 240 238 guest_modes_append_default(); 241 239 242 - while ((opt = getopt(argc, argv, "hm:u:d:b:s:v:o")) != -1) { 240 + while ((opt = getopt(argc, argv, "hm:u:d:b:s:v:c:o")) != -1) { 243 241 switch (opt) { 244 242 case 'm': 245 243 guest_modes_cmdline(optarg); ··· 266 264 TEST_ASSERT(nr_vcpus <= max_vcpus, 267 265 "Invalid number of vcpus, must be between 1 and %d", max_vcpus); 268 266 break; 267 + case 'c': 268 + cpulist = optarg; 269 + break; 269 270 case 'o': 270 271 p.partition_vcpu_memory_access = false; 271 272 break; ··· 282 277 if (p.uffd_mode == UFFDIO_REGISTER_MODE_MINOR && 283 278 !backing_src_is_shared(p.src_type)) { 284 279 TEST_FAIL("userfaultfd MINOR mode requires shared memory; pick a different -s"); 280 + } 281 + 282 + if (cpulist) { 283 + kvm_parse_vcpu_pinning(cpulist, memstress_args.vcpu_to_pcpu, 284 + nr_vcpus); 285 + memstress_args.pin_vcpus = true; 285 286 } 286 287 287 288 for_each_guest_mode(run_test, &p);
+1 -11
tools/testing/selftests/kvm/dirty_log_perf_test.c
··· 332 332 " so -w X means each page has an X%% chance of writing\n" 333 333 " and a (100-X)%% chance of reading.\n" 334 334 " (default: 100 i.e. all pages are written to.)\n"); 335 - printf(" -c: Pin tasks to physical CPUs. Takes a list of comma separated\n" 336 - " values (target pCPU), one for each vCPU, plus an optional\n" 337 - " entry for the main application task (specified via entry\n" 338 - " <nr_vcpus + 1>). If used, entries must be provided for all\n" 339 - " vCPUs, i.e. pinning vCPUs is all or nothing.\n\n" 340 - " E.g. to create 3 vCPUs, pin vCPU0=>pCPU22, vCPU1=>pCPU23,\n" 341 - " vCPU2=>pCPU24, and pin the application task to pCPU50:\n\n" 342 - " ./dirty_log_perf_test -v 3 -c 22,23,24,50\n\n" 343 - " To leave the application task unpinned, drop the final entry:\n\n" 344 - " ./dirty_log_perf_test -v 3 -c 22,23,24\n\n" 345 - " (default: no pinning)\n"); 335 + kvm_print_vcpu_pinning_help(); 346 336 puts(""); 347 337 exit(0); 348 338 }
+1
tools/testing/selftests/kvm/include/kvm_util_base.h
··· 733 733 struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); 734 734 735 735 void kvm_pin_this_task_to_pcpu(uint32_t pcpu); 736 + void kvm_print_vcpu_pinning_help(void); 736 737 void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[], 737 738 int nr_vcpus); 738 739
+17
tools/testing/selftests/kvm/lib/kvm_util.c
··· 494 494 return pcpu; 495 495 } 496 496 497 + void kvm_print_vcpu_pinning_help(void) 498 + { 499 + const char *name = program_invocation_name; 500 + 501 + printf(" -c: Pin tasks to physical CPUs. Takes a list of comma separated\n" 502 + " values (target pCPU), one for each vCPU, plus an optional\n" 503 + " entry for the main application task (specified via entry\n" 504 + " <nr_vcpus + 1>). If used, entries must be provided for all\n" 505 + " vCPUs, i.e. pinning vCPUs is all or nothing.\n\n" 506 + " E.g. to create 3 vCPUs, pin vCPU0=>pCPU22, vCPU1=>pCPU23,\n" 507 + " vCPU2=>pCPU24, and pin the application task to pCPU50:\n\n" 508 + " %s -v 3 -c 22,23,24,50\n\n" 509 + " To leave the application task unpinned, drop the final entry:\n\n" 510 + " %s -v 3 -c 22,23,24\n\n" 511 + " (default: no pinning)\n", name, name); 512 + } 513 + 497 514 void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[], 498 515 int nr_vcpus) 499 516 {