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