staticint num_processors(void)
{ long nproc = sysconf(_SC_NPROCESSORS_CONF); if (nproc < 0) {
perror("Unable to read number of processors\n"); exit(EXIT_FAILURE);
}
if (!child->output_seen) {
ksft_print_msg("%s no output seen\n", child->name);
fail = true;
}
if (child->exit_status != 0) {
ksft_print_msg("%s exited with error code %d\n",
child->name, child->exit_status);
fail = true;
}
ksft_test_result(!fail, "%s\n", child->name);
}
staticvoid handle_child_signal(int sig, siginfo_t *info, void *context)
{ int i; bool found = false;
for (i = 0; i < num_children; i++) { if (children[i].pid == info->si_pid) {
children[i].exited = true;
children[i].exit_status = info->si_status;
found = true; break;
}
}
if (!found)
ksft_print_msg("SIGCHLD for unknown PID %d with status %d\n",
info->si_pid, info->si_status);
}
staticvoid handle_exit_signal(int sig, siginfo_t *info, void *context)
{ int i;
/* If we're already exiting then don't signal again */ if (terminate) return;
ksft_print_msg("Got signal, exiting...\n");
terminate = true;
/* *Thisshouldberedundant,themainloopshouldcleanup *afterus,butforsafetystopeverythingwecanhere.
*/ for (i = 0; i < num_children; i++)
child_stop(&children[i]);
}
staticvoid start_fpsimd(struct child_data *child, int cpu, int copy)
{ int ret;
ret = asprintf(&child->name, "FPSIMD-%d-%d", cpu, copy); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./fpsimd-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid start_kernel(struct child_data *child, int cpu, int copy)
{ int ret;
ret = asprintf(&child->name, "KERNEL-%d-%d", cpu, copy); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./kernel-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid start_sve(struct child_data *child, int vl, int cpu)
{ int ret;
ret = prctl(PR_SVE_SET_VL, vl | PR_SVE_VL_INHERIT); if (ret < 0)
ksft_exit_fail_msg("Failed to set SVE VL %d\n", vl);
ret = asprintf(&child->name, "SVE-VL-%d-%d", vl, cpu); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./sve-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid start_ssve(struct child_data *child, int vl, int cpu)
{ int ret;
ret = asprintf(&child->name, "SSVE-VL-%d-%d", vl, cpu); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
ret = prctl(PR_SME_SET_VL, vl | PR_SME_VL_INHERIT); if (ret < 0)
ksft_exit_fail_msg("Failed to set SME VL %d\n", ret);
child_start(child, "./ssve-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid start_za(struct child_data *child, int vl, int cpu)
{ int ret;
ret = prctl(PR_SME_SET_VL, vl | PR_SVE_VL_INHERIT); if (ret < 0)
ksft_exit_fail_msg("Failed to set SME VL %d\n", ret);
ret = asprintf(&child->name, "ZA-VL-%d-%d", vl, cpu); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./za-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid start_zt(struct child_data *child, int cpu)
{ int ret;
ret = asprintf(&child->name, "ZT-%d", cpu); if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./zt-test");
ksft_print_msg("Started %s\n", child->name);
}
staticvoid probe_vls(int vls[], int *vl_count, int set_vl)
{ unsignedint vq; int vl;
int main(int argc, char **argv)
{ int ret; int timeout = 10 * (1000 / SIGNAL_INTERVAL_MS); int poll_interval = 5000; int cpus, i, j, c; int sve_vl_count, sme_vl_count; bool all_children_started = false; int seen_children; int sve_vls[MAX_VLS], sme_vls[MAX_VLS]; bool have_sme2; struct sigaction sa;
while ((c = getopt_long(argc, argv, "t:", options, NULL)) != -1) { switch (c) { case't':
ret = sscanf(optarg, "%d", &timeout); if (ret != 1)
ksft_exit_fail_msg("Failed to parse timeout %s\n",
optarg); break; default:
ksft_exit_fail_msg("Unknown argument\n");
}
}
ksft_print_msg("%d CPUs, %d SVE VLs, %d SME VLs, SME2 %s\n",
cpus, sve_vl_count, sme_vl_count,
have_sme2 ? "present" : "absent");
if (timeout > 0)
ksft_print_msg("Will run for %d\n", timeout); else
ksft_print_msg("Will run until terminated\n");
children = calloc(sizeof(*children), tests); if (!children)
ksft_exit_fail_msg("Unable to allocate child data\n");
ret = epoll_create1(EPOLL_CLOEXEC); if (ret < 0)
ksft_exit_fail_msg("epoll_create1() failed: %s (%d)\n",
strerror(errno), ret);
epoll_fd = ret;
/* Create a pipe which children will block on before execing */
ret = pipe(startup_pipe); if (ret != 0)
ksft_exit_fail_msg("Failed to create startup pipe: %s (%d)\n",
strerror(errno), errno);
/* Get signal handers ready before we start any children */
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handle_exit_signal;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigemptyset(&sa.sa_mask);
ret = sigaction(SIGINT, &sa, NULL); if (ret < 0)
ksft_print_msg("Failed to install SIGINT handler: %s (%d)\n",
strerror(errno), errno);
ret = sigaction(SIGTERM, &sa, NULL); if (ret < 0)
ksft_print_msg("Failed to install SIGTERM handler: %s (%d)\n",
strerror(errno), errno);
sa.sa_sigaction = handle_child_signal;
ret = sigaction(SIGCHLD, &sa, NULL); if (ret < 0)
ksft_print_msg("Failed to install SIGCHLD handler: %s (%d)\n",
strerror(errno), errno);
evs = calloc(tests, sizeof(*evs)); if (!evs)
ksft_exit_fail_msg("Failed to allocated %d epoll events\n",
tests);
for (i = 0; i < cpus; i++) {
start_fpsimd(&children[num_children++], i, 0);
start_kernel(&children[num_children++], i, 0);
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.