guest_data_prototype = malloc(demand_paging_size);
TEST_ASSERT(guest_data_prototype, "Failed to allocate buffer for guest data pattern");
memset(guest_data_prototype, 0xAB, demand_paging_size);
if (p->uffd_mode == UFFDIO_REGISTER_MODE_MINOR) {
num_uffds = p->single_uffd ? 1 : nr_vcpus; for (i = 0; i < num_uffds; i++) {
vcpu_args = &memstress_args.vcpu_args[i];
prefault_mem(addr_gpa2alias(vm, vcpu_args->gpa),
vcpu_args->pages * memstress_args.guest_page_size);
}
}
free(guest_data_prototype); if (p->uffd_mode)
free(uffd_descs);
}
staticvoid help(char *name)
{
puts("");
printf("usage: %s [-h] [-m vm_mode] [-u uffd_mode] [-a]\n" " [-d uffd_delay_usec] [-r readers_per_uffd] [-b memory]\n" " [-s type] [-v vcpus] [-c cpu_list] [-o]\n", name);
guest_modes_help();
printf(" -u: use userfaultfd to handle vCPU page faults. Mode is a\n" " UFFD registration mode: 'MISSING' or 'MINOR'.\n");
kvm_print_vcpu_pinning_help();
printf(" -a: Use a single userfaultfd for all of guest memory, instead of\n" " creating one for each region paged by a unique vCPU\n" " Set implicitly with -o, and no effect without -u.\n");
printf(" -d: add a delay in usec to the User Fault\n" " FD handler to simulate demand paging\n" " overheads. Ignored without -u.\n");
printf(" -r: Set the number of reader threads per uffd.\n");
printf(" -b: specify the size of the memory region which should be\n" " demand paged by each vCPU. e.g. 10M or 3G.\n" " Default: 1G\n");
backing_src_help("-s");
printf(" -v: specify the number of vCPUs to run.\n");
printf(" -o: Overlap guest memory accesses instead of partitioning\n" " them into a separate region of memory for each vCPU.\n");
puts(""); exit(0);
}
int main(int argc, char *argv[])
{ int max_vcpus = kvm_check_cap(KVM_CAP_MAX_VCPUS); constchar *cpulist = NULL; struct test_params p = {
.src_type = DEFAULT_VM_MEM_SRC,
.partition_vcpu_memory_access = true,
.readers_per_uffd = 1,
.single_uffd = false,
}; int opt;
guest_modes_append_default();
while ((opt = getopt(argc, argv, "ahom:u:d:b:s:v:c:r:")) != -1) { switch (opt) { case'm':
guest_modes_cmdline(optarg); break; case'u': if (!strcmp("MISSING", optarg))
p.uffd_mode = UFFDIO_REGISTER_MODE_MISSING; elseif (!strcmp("MINOR", optarg))
p.uffd_mode = UFFDIO_REGISTER_MODE_MINOR;
TEST_ASSERT(p.uffd_mode, "UFFD mode must be 'MISSING' or 'MINOR'."); break; case'a':
p.single_uffd = true; break; case'd':
p.uffd_delay = strtoul(optarg, NULL, 0);
TEST_ASSERT(p.uffd_delay >= 0, "A negative UFFD delay is not supported."); break; case'b':
guest_percpu_mem_size = parse_size(optarg); break; case's':
p.src_type = parse_backing_src_type(optarg); break; case'v':
nr_vcpus = atoi_positive("Number of vCPUs", optarg);
TEST_ASSERT(nr_vcpus <= max_vcpus, "Invalid number of vcpus, must be between 1 and %d", max_vcpus); break; case'c':
cpulist = optarg; break; case'o':
p.partition_vcpu_memory_access = false;
p.single_uffd = true; break; case'r':
p.readers_per_uffd = atoi(optarg);
TEST_ASSERT(p.readers_per_uffd >= 1, "Invalid number of readers per uffd %d: must be >=1",
p.readers_per_uffd); break; case'h': default:
help(argv[0]); break;
}
}
if (p.uffd_mode == UFFDIO_REGISTER_MODE_MINOR &&
!backing_src_is_shared(p.src_type)) {
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);
return0;
}
#else/* __NR_userfaultfd */
#warning"missing __NR_userfaultfd definition"
int main(void)
{
print_skip("__NR_userfaultfd must be present for userfaultfd test"); return KSFT_SKIP;
}
#endif/* __NR_userfaultfd */
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.