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