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