Commit d4ec586c authored by Peter Xu's avatar Peter Xu Committed by Sean Christopherson

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: default avatarPeter 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.comSigned-off-by: default avatarSean Christopherson <seanjc@google.com>
parent dfa78a20
...@@ -208,10 +208,11 @@ static void help(char *name) ...@@ -208,10 +208,11 @@ static void help(char *name)
{ {
puts(""); puts("");
printf("usage: %s [-h] [-m vm_mode] [-u uffd_mode] [-d uffd_delay_usec]\n" printf("usage: %s [-h] [-m vm_mode] [-u uffd_mode] [-d uffd_delay_usec]\n"
" [-b memory] [-s type] [-v vcpus] [-o]\n", name); " [-b memory] [-s type] [-v vcpus] [-c cpu_list] [-o]\n", name);
guest_modes_help(); guest_modes_help();
printf(" -u: use userfaultfd to handle vCPU page faults. Mode is a\n" printf(" -u: use userfaultfd to handle vCPU page faults. Mode is a\n"
" UFFD registration mode: 'MISSING' or 'MINOR'.\n"); " UFFD registration mode: 'MISSING' or 'MINOR'.\n");
kvm_print_vcpu_pinning_help();
printf(" -d: add a delay in usec to the User Fault\n" printf(" -d: add a delay in usec to the User Fault\n"
" FD handler to simulate demand paging\n" " FD handler to simulate demand paging\n"
" overheads. Ignored without -u.\n"); " overheads. Ignored without -u.\n");
...@@ -229,6 +230,7 @@ static void help(char *name) ...@@ -229,6 +230,7 @@ static void help(char *name)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int max_vcpus = kvm_check_cap(KVM_CAP_MAX_VCPUS); int max_vcpus = kvm_check_cap(KVM_CAP_MAX_VCPUS);
const char *cpulist = NULL;
struct test_params p = { struct test_params p = {
.src_type = DEFAULT_VM_MEM_SRC, .src_type = DEFAULT_VM_MEM_SRC,
.partition_vcpu_memory_access = true, .partition_vcpu_memory_access = true,
...@@ -237,7 +239,7 @@ int main(int argc, char *argv[]) ...@@ -237,7 +239,7 @@ int main(int argc, char *argv[])
guest_modes_append_default(); guest_modes_append_default();
while ((opt = getopt(argc, argv, "hm:u:d:b:s:v:o")) != -1) { while ((opt = getopt(argc, argv, "hm:u:d:b:s:v:c:o")) != -1) {
switch (opt) { switch (opt) {
case 'm': case 'm':
guest_modes_cmdline(optarg); guest_modes_cmdline(optarg);
...@@ -264,6 +266,9 @@ int main(int argc, char *argv[]) ...@@ -264,6 +266,9 @@ int main(int argc, char *argv[])
TEST_ASSERT(nr_vcpus <= max_vcpus, TEST_ASSERT(nr_vcpus <= max_vcpus,
"Invalid number of vcpus, must be between 1 and %d", max_vcpus); "Invalid number of vcpus, must be between 1 and %d", max_vcpus);
break; break;
case 'c':
cpulist = optarg;
break;
case 'o': case 'o':
p.partition_vcpu_memory_access = false; p.partition_vcpu_memory_access = false;
break; break;
...@@ -279,6 +284,12 @@ int main(int argc, char *argv[]) ...@@ -279,6 +284,12 @@ int main(int argc, char *argv[])
TEST_FAIL("userfaultfd MINOR mode requires shared memory; pick a different -s"); TEST_FAIL("userfaultfd MINOR mode requires shared memory; pick a different -s");
} }
if (cpulist) {
kvm_parse_vcpu_pinning(cpulist, memstress_args.vcpu_to_pcpu,
nr_vcpus);
memstress_args.pin_vcpus = true;
}
for_each_guest_mode(run_test, &p); for_each_guest_mode(run_test, &p);
return 0; return 0;
......
...@@ -332,17 +332,7 @@ static void help(char *name) ...@@ -332,17 +332,7 @@ static void help(char *name)
" so -w X means each page has an X%% chance of writing\n" " so -w X means each page has an X%% chance of writing\n"
" and a (100-X)%% chance of reading.\n" " and a (100-X)%% chance of reading.\n"
" (default: 100 i.e. all pages are written to.)\n"); " (default: 100 i.e. all pages are written to.)\n");
printf(" -c: Pin tasks to physical CPUs. Takes a list of comma separated\n" kvm_print_vcpu_pinning_help();
" values (target pCPU), one for each vCPU, plus an optional\n"
" entry for the main application task (specified via entry\n"
" <nr_vcpus + 1>). If used, entries must be provided for all\n"
" vCPUs, i.e. pinning vCPUs is all or nothing.\n\n"
" E.g. to create 3 vCPUs, pin vCPU0=>pCPU22, vCPU1=>pCPU23,\n"
" vCPU2=>pCPU24, and pin the application task to pCPU50:\n\n"
" ./dirty_log_perf_test -v 3 -c 22,23,24,50\n\n"
" To leave the application task unpinned, drop the final entry:\n\n"
" ./dirty_log_perf_test -v 3 -c 22,23,24\n\n"
" (default: no pinning)\n");
puts(""); puts("");
exit(0); exit(0);
} }
......
...@@ -733,6 +733,7 @@ static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcpu, ...@@ -733,6 +733,7 @@ static inline struct kvm_vm *vm_create_with_one_vcpu(struct kvm_vcpu **vcpu,
struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm); struct kvm_vcpu *vm_recreate_with_one_vcpu(struct kvm_vm *vm);
void kvm_pin_this_task_to_pcpu(uint32_t pcpu); void kvm_pin_this_task_to_pcpu(uint32_t pcpu);
void kvm_print_vcpu_pinning_help(void);
void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[], void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[],
int nr_vcpus); int nr_vcpus);
......
...@@ -494,6 +494,23 @@ static uint32_t parse_pcpu(const char *cpu_str, const cpu_set_t *allowed_mask) ...@@ -494,6 +494,23 @@ static uint32_t parse_pcpu(const char *cpu_str, const cpu_set_t *allowed_mask)
return pcpu; return pcpu;
} }
void kvm_print_vcpu_pinning_help(void)
{
const char *name = program_invocation_name;
printf(" -c: Pin tasks to physical CPUs. Takes a list of comma separated\n"
" values (target pCPU), one for each vCPU, plus an optional\n"
" entry for the main application task (specified via entry\n"
" <nr_vcpus + 1>). If used, entries must be provided for all\n"
" vCPUs, i.e. pinning vCPUs is all or nothing.\n\n"
" E.g. to create 3 vCPUs, pin vCPU0=>pCPU22, vCPU1=>pCPU23,\n"
" vCPU2=>pCPU24, and pin the application task to pCPU50:\n\n"
" %s -v 3 -c 22,23,24,50\n\n"
" To leave the application task unpinned, drop the final entry:\n\n"
" %s -v 3 -c 22,23,24\n\n"
" (default: no pinning)\n", name, name);
}
void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[], void kvm_parse_vcpu_pinning(const char *pcpus_string, uint32_t vcpu_to_pcpu[],
int nr_vcpus) int nr_vcpus)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment