1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2022 ARM Limited. 4 */ 5 6 #define _GNU_SOURCE 7 #define _POSIX_C_SOURCE 199309L 8 9 #include <errno.h> 10 #include <getopt.h> 11 #include <poll.h> 12 #include <signal.h> 13 #include <stdbool.h> 14 #include <stddef.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <unistd.h> 19 #include <sys/auxv.h> 20 #include <sys/epoll.h> 21 #include <sys/prctl.h> 22 #include <sys/types.h> 23 #include <sys/uio.h> 24 #include <sys/wait.h> 25 #include <asm/hwcap.h> 26 27 #include "../../kselftest.h" 28 29 #define MAX_VLS 16 30 31 struct child_data { 32 char *name, *output; 33 pid_t pid; 34 int stdout; 35 bool output_seen; 36 bool exited; 37 int exit_status; 38 }; 39 40 static int epoll_fd; 41 static struct child_data *children; 42 static int num_children; 43 static bool terminate; 44 45 static void drain_output(bool flush); 46 47 static int num_processors(void) 48 { 49 long nproc = sysconf(_SC_NPROCESSORS_CONF); 50 if (nproc < 0) { 51 perror("Unable to read number of processors\n"); 52 exit(EXIT_FAILURE); 53 } 54 55 return nproc; 56 } 57 58 static void child_start(struct child_data *child, const char *program) 59 { 60 int ret, pipefd[2], i; 61 struct epoll_event ev; 62 63 ret = pipe(pipefd); 64 if (ret != 0) 65 ksft_exit_fail_msg("Failed to create stdout pipe: %s (%d)\n", 66 strerror(errno), errno); 67 68 child->pid = fork(); 69 if (child->pid == -1) 70 ksft_exit_fail_msg("fork() failed: %s (%d)\n", 71 strerror(errno), errno); 72 73 if (!child->pid) { 74 /* 75 * In child, replace stdout with the pipe, errors to 76 * stderr from here as kselftest prints to stdout. 77 */ 78 ret = dup2(pipefd[1], 1); 79 if (ret == -1) { 80 fprintf(stderr, "dup2() %d\n", errno); 81 exit(EXIT_FAILURE); 82 } 83 84 /* 85 * Very dumb mechanism to clean open FDs other than 86 * stdio. We don't want O_CLOEXEC for the pipes... 87 */ 88 for (i = 3; i < 8192; i++) 89 close(i); 90 91 ret = execl(program, program, NULL); 92 fprintf(stderr, "execl(%s) failed: %d (%s)\n", 93 program, errno, strerror(errno)); 94 95 exit(EXIT_FAILURE); 96 } else { 97 /* 98 * In parent, remember the child and close our copy of the 99 * write side of stdout. 100 */ 101 close(pipefd[1]); 102 child->stdout = pipefd[0]; 103 child->output = NULL; 104 child->exited = false; 105 child->output_seen = false; 106 107 ev.events = EPOLLIN | EPOLLHUP; 108 ev.data.ptr = child; 109 110 ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, child->stdout, &ev); 111 if (ret < 0) { 112 ksft_exit_fail_msg("%s EPOLL_CTL_ADD failed: %s (%d)\n", 113 child->name, strerror(errno), errno); 114 } 115 116 /* 117 * Keep output flowing during child startup so logs 118 * are more timely, can help debugging. 119 */ 120 drain_output(false); 121 } 122 } 123 124 static bool child_output_read(struct child_data *child) 125 { 126 char read_data[1024]; 127 char work[1024]; 128 int ret, len, cur_work, cur_read; 129 130 ret = read(child->stdout, read_data, sizeof(read_data)); 131 if (ret < 0) { 132 if (errno == EINTR) 133 return true; 134 135 ksft_print_msg("%s: read() failed: %s (%d)\n", 136 child->name, strerror(errno), 137 errno); 138 return false; 139 } 140 len = ret; 141 142 child->output_seen = true; 143 144 /* Pick up any partial read */ 145 if (child->output) { 146 strncpy(work, child->output, sizeof(work) - 1); 147 cur_work = strnlen(work, sizeof(work)); 148 free(child->output); 149 child->output = NULL; 150 } else { 151 cur_work = 0; 152 } 153 154 cur_read = 0; 155 while (cur_read < len) { 156 work[cur_work] = read_data[cur_read++]; 157 158 if (work[cur_work] == '\n') { 159 work[cur_work] = '\0'; 160 ksft_print_msg("%s: %s\n", child->name, work); 161 cur_work = 0; 162 } else { 163 cur_work++; 164 } 165 } 166 167 if (cur_work) { 168 work[cur_work] = '\0'; 169 ret = asprintf(&child->output, "%s", work); 170 if (ret == -1) 171 ksft_exit_fail_msg("Out of memory\n"); 172 } 173 174 return false; 175 } 176 177 static void child_output(struct child_data *child, uint32_t events, 178 bool flush) 179 { 180 bool read_more; 181 182 if (events & EPOLLIN) { 183 do { 184 read_more = child_output_read(child); 185 } while (read_more); 186 } 187 188 if (events & EPOLLHUP) { 189 close(child->stdout); 190 child->stdout = -1; 191 flush = true; 192 } 193 194 if (flush && child->output) { 195 ksft_print_msg("%s: %s<EOF>\n", child->name, child->output); 196 free(child->output); 197 child->output = NULL; 198 } 199 } 200 201 static void child_tickle(struct child_data *child) 202 { 203 if (child->output_seen && !child->exited) 204 kill(child->pid, SIGUSR2); 205 } 206 207 static void child_stop(struct child_data *child) 208 { 209 if (!child->exited) 210 kill(child->pid, SIGTERM); 211 } 212 213 static void child_cleanup(struct child_data *child) 214 { 215 pid_t ret; 216 int status; 217 bool fail = false; 218 219 if (!child->exited) { 220 do { 221 ret = waitpid(child->pid, &status, 0); 222 if (ret == -1 && errno == EINTR) 223 continue; 224 225 if (ret == -1) { 226 ksft_print_msg("waitpid(%d) failed: %s (%d)\n", 227 child->pid, strerror(errno), 228 errno); 229 fail = true; 230 break; 231 } 232 } while (!WIFEXITED(status)); 233 child->exit_status = WEXITSTATUS(status); 234 } 235 236 if (!child->output_seen) { 237 ksft_print_msg("%s no output seen\n", child->name); 238 fail = true; 239 } 240 241 if (child->exit_status != 0) { 242 ksft_print_msg("%s exited with error code %d\n", 243 child->name, child->exit_status); 244 fail = true; 245 } 246 247 ksft_test_result(!fail, "%s\n", child->name); 248 } 249 250 static void handle_child_signal(int sig, siginfo_t *info, void *context) 251 { 252 int i; 253 bool found = false; 254 255 for (i = 0; i < num_children; i++) { 256 if (children[i].pid == info->si_pid) { 257 children[i].exited = true; 258 children[i].exit_status = info->si_status; 259 found = true; 260 break; 261 } 262 } 263 264 if (!found) 265 ksft_print_msg("SIGCHLD for unknown PID %d with status %d\n", 266 info->si_pid, info->si_status); 267 } 268 269 static void handle_exit_signal(int sig, siginfo_t *info, void *context) 270 { 271 int i; 272 273 /* If we're already exiting then don't signal again */ 274 if (terminate) 275 return; 276 277 ksft_print_msg("Got signal, exiting...\n"); 278 279 terminate = true; 280 281 /* 282 * This should be redundant, the main loop should clean up 283 * after us, but for safety stop everything we can here. 284 */ 285 for (i = 0; i < num_children; i++) 286 child_stop(&children[i]); 287 } 288 289 static void start_fpsimd(struct child_data *child, int cpu, int copy) 290 { 291 int ret; 292 293 child_start(child, "./fpsimd-test"); 294 295 ret = asprintf(&child->name, "FPSIMD-%d-%d", cpu, copy); 296 if (ret == -1) 297 ksft_exit_fail_msg("asprintf() failed\n"); 298 299 ksft_print_msg("Started %s\n", child->name); 300 } 301 302 static void start_sve(struct child_data *child, int vl, int cpu) 303 { 304 int ret; 305 306 ret = prctl(PR_SVE_SET_VL, vl | PR_SVE_VL_INHERIT); 307 if (ret < 0) 308 ksft_exit_fail_msg("Failed to set SVE VL %d\n", vl); 309 310 child_start(child, "./sve-test"); 311 312 ret = asprintf(&child->name, "SVE-VL-%d-%d", vl, cpu); 313 if (ret == -1) 314 ksft_exit_fail_msg("asprintf() failed\n"); 315 316 ksft_print_msg("Started %s\n", child->name); 317 } 318 319 static void start_ssve(struct child_data *child, int vl, int cpu) 320 { 321 int ret; 322 323 ret = prctl(PR_SME_SET_VL, vl | PR_SME_VL_INHERIT); 324 if (ret < 0) 325 ksft_exit_fail_msg("Failed to set SME VL %d\n", ret); 326 327 child_start(child, "./ssve-test"); 328 329 ret = asprintf(&child->name, "SSVE-VL-%d-%d", vl, cpu); 330 if (ret == -1) 331 ksft_exit_fail_msg("asprintf() failed\n"); 332 333 ksft_print_msg("Started %s\n", child->name); 334 } 335 336 static void start_za(struct child_data *child, int vl, int cpu) 337 { 338 int ret; 339 340 ret = prctl(PR_SME_SET_VL, vl | PR_SVE_VL_INHERIT); 341 if (ret < 0) 342 ksft_exit_fail_msg("Failed to set SME VL %d\n", ret); 343 344 child_start(child, "./za-test"); 345 346 ret = asprintf(&child->name, "ZA-VL-%d-%d", vl, cpu); 347 if (ret == -1) 348 ksft_exit_fail_msg("asprintf() failed\n"); 349 350 ksft_print_msg("Started %s\n", child->name); 351 } 352 353 static void probe_vls(int vls[], int *vl_count, int set_vl) 354 { 355 unsigned int vq; 356 int vl; 357 358 *vl_count = 0; 359 360 for (vq = SVE_VQ_MAX; vq > 0; --vq) { 361 vl = prctl(set_vl, vq * 16); 362 if (vl == -1) 363 ksft_exit_fail_msg("SET_VL failed: %s (%d)\n", 364 strerror(errno), errno); 365 366 vl &= PR_SVE_VL_LEN_MASK; 367 368 vq = sve_vq_from_vl(vl); 369 370 vls[*vl_count] = vl; 371 *vl_count += 1; 372 } 373 } 374 375 /* Handle any pending output without blocking */ 376 static void drain_output(bool flush) 377 { 378 struct epoll_event ev; 379 int ret = 1; 380 381 while (ret > 0) { 382 ret = epoll_wait(epoll_fd, &ev, 1, 0); 383 if (ret < 0) { 384 if (errno == EINTR) 385 continue; 386 ksft_print_msg("epoll_wait() failed: %s (%d)\n", 387 strerror(errno), errno); 388 } 389 390 if (ret == 1) 391 child_output(ev.data.ptr, ev.events, flush); 392 } 393 } 394 395 static const struct option options[] = { 396 { "timeout", required_argument, NULL, 't' }, 397 { } 398 }; 399 400 int main(int argc, char **argv) 401 { 402 int ret; 403 int timeout = 10; 404 int cpus, tests, i, j, c; 405 int sve_vl_count, sme_vl_count, fpsimd_per_cpu; 406 int sve_vls[MAX_VLS], sme_vls[MAX_VLS]; 407 struct epoll_event ev; 408 struct sigaction sa; 409 410 while ((c = getopt_long(argc, argv, "t:", options, NULL)) != -1) { 411 switch (c) { 412 case 't': 413 ret = sscanf(optarg, "%d", &timeout); 414 if (ret != 1) 415 ksft_exit_fail_msg("Failed to parse timeout %s\n", 416 optarg); 417 break; 418 default: 419 ksft_exit_fail_msg("Unknown argument\n"); 420 } 421 } 422 423 cpus = num_processors(); 424 tests = 0; 425 426 if (getauxval(AT_HWCAP) & HWCAP_SVE) { 427 probe_vls(sve_vls, &sve_vl_count, PR_SVE_SET_VL); 428 tests += sve_vl_count * cpus; 429 } else { 430 sve_vl_count = 0; 431 } 432 433 if (getauxval(AT_HWCAP2) & HWCAP2_SME) { 434 probe_vls(sme_vls, &sme_vl_count, PR_SME_SET_VL); 435 tests += sme_vl_count * cpus * 2; 436 } else { 437 sme_vl_count = 0; 438 } 439 440 /* Force context switching if we only have FPSIMD */ 441 if (!sve_vl_count && !sme_vl_count) 442 fpsimd_per_cpu = 2; 443 else 444 fpsimd_per_cpu = 1; 445 tests += cpus * fpsimd_per_cpu; 446 447 ksft_print_header(); 448 ksft_set_plan(tests); 449 450 ksft_print_msg("%d CPUs, %d SVE VLs, %d SME VLs\n", 451 cpus, sve_vl_count, sme_vl_count); 452 453 if (timeout > 0) 454 ksft_print_msg("Will run for %ds\n", timeout); 455 else 456 ksft_print_msg("Will run until terminated\n"); 457 458 children = calloc(sizeof(*children), tests); 459 if (!children) 460 ksft_exit_fail_msg("Unable to allocate child data\n"); 461 462 ret = epoll_create1(EPOLL_CLOEXEC); 463 if (ret < 0) 464 ksft_exit_fail_msg("epoll_create1() failed: %s (%d)\n", 465 strerror(errno), ret); 466 epoll_fd = ret; 467 468 /* Get signal handers ready before we start any children */ 469 memset(&sa, 0, sizeof(sa)); 470 sa.sa_sigaction = handle_exit_signal; 471 sa.sa_flags = SA_RESTART | SA_SIGINFO; 472 sigemptyset(&sa.sa_mask); 473 ret = sigaction(SIGINT, &sa, NULL); 474 if (ret < 0) 475 ksft_print_msg("Failed to install SIGINT handler: %s (%d)\n", 476 strerror(errno), errno); 477 ret = sigaction(SIGTERM, &sa, NULL); 478 if (ret < 0) 479 ksft_print_msg("Failed to install SIGTERM handler: %s (%d)\n", 480 strerror(errno), errno); 481 sa.sa_sigaction = handle_child_signal; 482 ret = sigaction(SIGCHLD, &sa, NULL); 483 if (ret < 0) 484 ksft_print_msg("Failed to install SIGCHLD handler: %s (%d)\n", 485 strerror(errno), errno); 486 487 for (i = 0; i < cpus; i++) { 488 for (j = 0; j < fpsimd_per_cpu; j++) 489 start_fpsimd(&children[num_children++], i, j); 490 491 for (j = 0; j < sve_vl_count; j++) 492 start_sve(&children[num_children++], sve_vls[j], i); 493 494 for (j = 0; j < sme_vl_count; j++) { 495 start_ssve(&children[num_children++], sme_vls[j], i); 496 start_za(&children[num_children++], sme_vls[j], i); 497 } 498 } 499 500 for (;;) { 501 /* Did we get a signal asking us to exit? */ 502 if (terminate) 503 break; 504 505 /* 506 * Timeout is counted in seconds with no output, the 507 * tests print during startup then are silent when 508 * running so this should ensure they all ran enough 509 * to install the signal handler, this is especially 510 * useful in emulation where we will both be slow and 511 * likely to have a large set of VLs. 512 */ 513 ret = epoll_wait(epoll_fd, &ev, 1, 1000); 514 if (ret < 0) { 515 if (errno == EINTR) 516 continue; 517 ksft_exit_fail_msg("epoll_wait() failed: %s (%d)\n", 518 strerror(errno), errno); 519 } 520 521 /* Output? */ 522 if (ret == 1) { 523 child_output(ev.data.ptr, ev.events, false); 524 continue; 525 } 526 527 /* Otherwise epoll_wait() timed out */ 528 529 for (i = 0; i < num_children; i++) 530 child_tickle(&children[i]); 531 532 /* Negative timeout means run indefinitely */ 533 if (timeout < 0) 534 continue; 535 if (--timeout == 0) 536 break; 537 } 538 539 ksft_print_msg("Finishing up...\n"); 540 terminate = true; 541 542 for (i = 0; i < tests; i++) 543 child_stop(&children[i]); 544 545 drain_output(false); 546 547 for (i = 0; i < tests; i++) 548 child_cleanup(&children[i]); 549 550 drain_output(true); 551 552 ksft_print_cnts(); 553 554 return 0; 555 } 556