Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf test: Sort tests placing exclusive tests last

This allows a uniform test numbering even though two passes are used
to execute them.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Veronika Molnarova <vmolnaro@redhat.com>
Link: https://lore.kernel.org/r/20241025192109.132482-11-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
7449a4d6 553d5efe

+84 -41
+84 -41
tools/perf/tests/builtin-test.c
··· 137 137 NULL, 138 138 }; 139 139 140 - static struct test_suite **tests[] = { 141 - generic_tests, 142 - arch_tests, 143 - NULL, /* shell tests created at runtime. */ 144 - }; 145 - 146 140 static struct test_workload *workloads[] = { 147 141 &workload__noploop, 148 142 &workload__thloop, ··· 462 468 return start_command(&(*child)->process); 463 469 } 464 470 465 - #define for_each_test(j, k, t) \ 466 - for (j = 0, k = 0; j < ARRAY_SIZE(tests); j++, k = 0) \ 467 - while ((t = tests[j][k++]) != NULL) 468 - 469 471 /* State outside of __cmd_test for the sake of the signal handler. */ 470 472 471 473 static size_t num_tests; ··· 473 483 siglongjmp(cmd_test_jmp_buf, sig); 474 484 } 475 485 476 - static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) 486 + static int __cmd_test(struct test_suite **suites, int argc, const char *argv[], 487 + struct intlist *skiplist) 477 488 { 478 - struct test_suite *t; 479 489 static int width = 0; 480 - unsigned int j, k; 481 490 int err = 0; 482 491 483 - for_each_test(j, k, t) { 484 - int len = strlen(test_description(t, -1)); 492 + for (struct test_suite **t = suites; *t; t++) { 493 + int len = strlen(test_description(*t, -1)); 485 494 486 495 if (width < len) 487 496 width = len; 488 497 489 - if (has_subtests(t)) { 490 - for (int subi = 0, subn = num_subtests(t); subi < subn; subi++) { 491 - len = strlen(test_description(t, subi)); 498 + if (has_subtests(*t)) { 499 + for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) { 500 + len = strlen(test_description(*t, subi)); 492 501 if (width < len) 493 502 width = len; 494 503 num_tests++; ··· 529 540 int child_test_num = 0; 530 541 int i = 0; 531 542 532 - for_each_test(j, k, t) { 543 + for (struct test_suite **t = suites; *t; t++) { 533 544 int curr = i++; 534 545 535 - if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) { 546 + if (!perf_test__matches(test_description(*t, -1), curr, argc, argv)) { 536 547 /* 537 548 * Test suite shouldn't be run based on 538 549 * description. See if subtest should. 539 550 */ 540 551 bool skip = true; 541 552 542 - for (int subi = 0, subn = num_subtests(t); subi < subn; subi++) { 543 - if (perf_test__matches(test_description(t, subi), 553 + for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) { 554 + if (perf_test__matches(test_description(*t, subi), 544 555 curr, argc, argv)) 545 556 skip = false; 546 557 } ··· 550 561 } 551 562 552 563 if (intlist__find(skiplist, i)) { 553 - pr_info("%3d: %-*s:", curr + 1, width, test_description(t, -1)); 564 + pr_info("%3d: %-*s:", curr + 1, width, test_description(*t, -1)); 554 565 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); 555 566 continue; 556 567 } 557 568 558 - if (!has_subtests(t)) { 559 - err = start_test(t, curr, -1, &child_tests[child_test_num++], 569 + if (!has_subtests(*t)) { 570 + err = start_test(*t, curr, -1, &child_tests[child_test_num++], 560 571 width, pass); 561 572 if (err) 562 573 goto err_out; 563 574 continue; 564 575 } 565 - for (int subi = 0, subn = num_subtests(t); subi < subn; subi++) { 566 - if (!perf_test__matches(test_description(t, subi), 576 + for (int subi = 0, subn = num_subtests(*t); subi < subn; subi++) { 577 + if (!perf_test__matches(test_description(*t, subi), 567 578 curr, argc, argv)) 568 579 continue; 569 580 570 - err = start_test(t, curr, subi, &child_tests[child_test_num++], 581 + err = start_test(*t, curr, subi, &child_tests[child_test_num++], 571 582 width, pass); 572 583 if (err) 573 584 goto err_out; ··· 591 602 return err; 592 603 } 593 604 594 - static int perf_test__list(int argc, const char **argv) 605 + static int perf_test__list(struct test_suite **suites, int argc, const char **argv) 595 606 { 596 - unsigned int j, k; 597 - struct test_suite *t; 598 607 int i = 0; 599 608 600 - for_each_test(j, k, t) { 609 + for (struct test_suite **t = suites; *t; t++) { 601 610 int curr = i++; 602 611 603 - if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) 612 + if (!perf_test__matches(test_description(*t, -1), curr, argc, argv)) 604 613 continue; 605 614 606 - pr_info("%3d: %s\n", i, test_description(t, -1)); 615 + pr_info("%3d: %s\n", i, test_description(*t, -1)); 607 616 608 - if (has_subtests(t)) { 609 - int subn = num_subtests(t); 617 + if (has_subtests(*t)) { 618 + int subn = num_subtests(*t); 610 619 int subi; 611 620 612 621 for (subi = 0; subi < subn; subi++) 613 622 pr_info("%3d:%1d: %s\n", i, subi + 1, 614 - test_description(t, subi)); 623 + test_description(*t, subi)); 615 624 } 616 625 } 617 626 return 0; ··· 648 661 return 0; 649 662 } 650 663 664 + static struct test_suite **build_suites(void) 665 + { 666 + /* 667 + * TODO: suites is static to avoid needing to clean up the scripts tests 668 + * for leak sanitizer. 669 + */ 670 + static struct test_suite **suites[] = { 671 + generic_tests, 672 + arch_tests, 673 + NULL, 674 + }; 675 + struct test_suite **result; 676 + struct test_suite *t; 677 + size_t n = 0, num_suites = 0; 678 + 679 + if (suites[2] == NULL) 680 + suites[2] = create_script_test_suites(); 681 + 682 + #define for_each_test(t) \ 683 + for (size_t i = 0, j = 0; i < ARRAY_SIZE(suites); i++, j = 0) \ 684 + while ((t = suites[i][j++]) != NULL) 685 + 686 + for_each_test(t) 687 + num_suites++; 688 + 689 + result = calloc(num_suites + 1, sizeof(struct test_suite *)); 690 + 691 + for (int pass = 1; pass <= 2; pass++) { 692 + for_each_test(t) { 693 + bool exclusive = false; 694 + 695 + if (!has_subtests(t)) { 696 + exclusive = test_exclusive(t, -1); 697 + } else { 698 + for (int subi = 0, subn = num_subtests(t); subi < subn; subi++) { 699 + if (test_exclusive(t, subi)) { 700 + exclusive = true; 701 + break; 702 + } 703 + } 704 + } 705 + if ((!exclusive && pass == 1) || (exclusive && pass == 2)) 706 + result[n++] = t; 707 + } 708 + } 709 + return result; 710 + #undef for_each_test 711 + } 712 + 651 713 int cmd_test(int argc, const char **argv) 652 714 { 653 715 const char *test_usage[] = { ··· 724 688 const char * const test_subcommands[] = { "list", NULL }; 725 689 struct intlist *skiplist = NULL; 726 690 int ret = hists__init(); 691 + struct test_suite **suites; 727 692 728 693 if (ret < 0) 729 694 return ret; ··· 734 697 /* Unbuffered output */ 735 698 setvbuf(stdout, NULL, _IONBF, 0); 736 699 737 - tests[2] = create_script_test_suites(); 738 700 argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); 739 - if (argc >= 1 && !strcmp(argv[0], "list")) 740 - return perf_test__list(argc - 1, argv + 1); 701 + if (argc >= 1 && !strcmp(argv[0], "list")) { 702 + suites = build_suites(); 703 + ret = perf_test__list(suites, argc - 1, argv + 1); 704 + free(suites); 705 + return ret; 706 + } 741 707 742 708 if (workload) 743 709 return run_workload(workload, argc, argv); ··· 768 728 */ 769 729 rlimit__bump_memlock(); 770 730 771 - return __cmd_test(argc, argv, skiplist); 731 + suites = build_suites(); 732 + ret = __cmd_test(suites, argc, argv, skiplist); 733 + free(suites); 734 + return ret; 772 735 }