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.

kunit: reduce stack usage in kunit_run_tests()

Some of the recent changes to the kunit framework caused the stack usage
for kunit_run_tests() to grow higher than most other kernel functions,
which triggers a warning when CONFIG_FRAME_WARN is set to a relatively
low value:

lib/kunit/test.c: In function 'kunit_run_tests':
lib/kunit/test.c:801:1: error: the frame size of 1312 bytes is larger than 1280 bytes [-Werror=frame-larger-than=]

Split out the inner loop into a separate function to ensure that each
function remains under the limit, and pass the kunit_result_stats
structures by reference to avoid excessive copies.

Fixed checkpatch warnings at commit time:
Shuah Khan <skhan@linuxfoundation.org>

Cc: Carlos Llamas <cmllamas@google.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Arnd Bergmann and committed by
Shuah Khan
b11b9b67 40804c49

+125 -106
+125 -106
lib/kunit/test.c
··· 94 94 unsigned long total; 95 95 }; 96 96 97 - static bool kunit_should_print_stats(struct kunit_result_stats stats) 97 + static bool kunit_should_print_stats(struct kunit_result_stats *stats) 98 98 { 99 99 if (kunit_stats_enabled == 0) 100 100 return false; ··· 102 102 if (kunit_stats_enabled == 2) 103 103 return true; 104 104 105 - return (stats.total > 1); 105 + return (stats->total > 1); 106 106 } 107 107 108 108 static void kunit_print_test_stats(struct kunit *test, 109 - struct kunit_result_stats stats) 109 + struct kunit_result_stats *stats) 110 110 { 111 111 if (!kunit_should_print_stats(stats)) 112 112 return; ··· 115 115 KUNIT_SUBTEST_INDENT 116 116 "# %s: pass:%lu fail:%lu skip:%lu total:%lu", 117 117 test->name, 118 - stats.passed, 119 - stats.failed, 120 - stats.skipped, 121 - stats.total); 118 + stats->passed, 119 + stats->failed, 120 + stats->skipped, 121 + stats->total); 122 122 } 123 123 124 124 /* Append formatted message to log. */ ··· 600 600 } 601 601 602 602 static void kunit_print_suite_stats(struct kunit_suite *suite, 603 - struct kunit_result_stats suite_stats, 604 - struct kunit_result_stats param_stats) 603 + struct kunit_result_stats *suite_stats, 604 + struct kunit_result_stats *param_stats) 605 605 { 606 606 if (kunit_should_print_stats(suite_stats)) { 607 607 kunit_log(KERN_INFO, suite, 608 608 "# %s: pass:%lu fail:%lu skip:%lu total:%lu", 609 609 suite->name, 610 - suite_stats.passed, 611 - suite_stats.failed, 612 - suite_stats.skipped, 613 - suite_stats.total); 610 + suite_stats->passed, 611 + suite_stats->failed, 612 + suite_stats->skipped, 613 + suite_stats->total); 614 614 } 615 615 616 616 if (kunit_should_print_stats(param_stats)) { 617 617 kunit_log(KERN_INFO, suite, 618 618 "# Totals: pass:%lu fail:%lu skip:%lu total:%lu", 619 - param_stats.passed, 620 - param_stats.failed, 621 - param_stats.skipped, 622 - param_stats.total); 619 + param_stats->passed, 620 + param_stats->failed, 621 + param_stats->skipped, 622 + param_stats->total); 623 623 } 624 624 } 625 625 ··· 681 681 } 682 682 } 683 683 684 - int kunit_run_tests(struct kunit_suite *suite) 684 + static noinline_for_stack void 685 + kunit_run_param_test(struct kunit_suite *suite, struct kunit_case *test_case, 686 + struct kunit *test, 687 + struct kunit_result_stats *suite_stats, 688 + struct kunit_result_stats *total_stats, 689 + struct kunit_result_stats *param_stats) 685 690 { 686 691 char param_desc[KUNIT_PARAM_DESC_SIZE]; 692 + const void *curr_param; 693 + 694 + kunit_init_parent_param_test(test_case, test); 695 + if (test_case->status == KUNIT_FAILURE) { 696 + kunit_update_stats(param_stats, test->status); 697 + return; 698 + } 699 + /* Get initial param. */ 700 + param_desc[0] = '\0'; 701 + /* TODO: Make generate_params try-catch */ 702 + curr_param = test_case->generate_params(test, NULL, param_desc); 703 + test_case->status = KUNIT_SKIPPED; 704 + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT 705 + "KTAP version 1\n"); 706 + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT 707 + "# Subtest: %s", test_case->name); 708 + if (test->params_array.params && 709 + test_case->generate_params == kunit_array_gen_params) { 710 + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT 711 + KUNIT_SUBTEST_INDENT "1..%zd\n", 712 + test->params_array.num_params); 713 + } 714 + 715 + while (curr_param) { 716 + struct kunit param_test = { 717 + .param_value = curr_param, 718 + .param_index = ++test->param_index, 719 + .parent = test, 720 + }; 721 + kunit_init_test(&param_test, test_case->name, NULL); 722 + param_test.log = test_case->log; 723 + kunit_run_case_catch_errors(suite, test_case, &param_test); 724 + 725 + if (param_desc[0] == '\0') { 726 + snprintf(param_desc, sizeof(param_desc), 727 + "param-%d", param_test.param_index); 728 + } 729 + 730 + kunit_print_ok_not_ok(&param_test, KUNIT_LEVEL_CASE_PARAM, 731 + param_test.status, 732 + param_test.param_index, 733 + param_desc, 734 + param_test.status_comment); 735 + 736 + kunit_update_stats(param_stats, param_test.status); 737 + 738 + /* Get next param. */ 739 + param_desc[0] = '\0'; 740 + curr_param = test_case->generate_params(test, curr_param, 741 + param_desc); 742 + } 743 + /* 744 + * TODO: Put into a try catch. Since we don't need suite->exit 745 + * for it we can't reuse kunit_try_run_cleanup for this yet. 746 + */ 747 + if (test_case->param_exit) 748 + test_case->param_exit(test); 749 + /* TODO: Put this kunit_cleanup into a try-catch. */ 750 + kunit_cleanup(test); 751 + } 752 + 753 + static noinline_for_stack void 754 + kunit_run_one_test(struct kunit_suite *suite, struct kunit_case *test_case, 755 + struct kunit_result_stats *suite_stats, 756 + struct kunit_result_stats *total_stats) 757 + { 758 + struct kunit test = { .param_value = NULL, .param_index = 0 }; 759 + struct kunit_result_stats param_stats = { 0 }; 760 + 761 + kunit_init_test(&test, test_case->name, test_case->log); 762 + if (test_case->status == KUNIT_SKIPPED) { 763 + /* Test marked as skip */ 764 + test.status = KUNIT_SKIPPED; 765 + kunit_update_stats(&param_stats, test.status); 766 + } else if (!test_case->generate_params) { 767 + /* Non-parameterised test. */ 768 + test_case->status = KUNIT_SKIPPED; 769 + kunit_run_case_catch_errors(suite, test_case, &test); 770 + kunit_update_stats(&param_stats, test.status); 771 + } else { 772 + kunit_run_param_test(suite, test_case, &test, suite_stats, 773 + total_stats, &param_stats); 774 + } 775 + kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE); 776 + 777 + kunit_print_test_stats(&test, &param_stats); 778 + 779 + kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status, 780 + kunit_test_case_num(suite, test_case), 781 + test_case->name, 782 + test.status_comment); 783 + 784 + kunit_update_stats(suite_stats, test_case->status); 785 + kunit_accumulate_stats(total_stats, param_stats); 786 + } 787 + 788 + 789 + int kunit_run_tests(struct kunit_suite *suite) 790 + { 687 791 struct kunit_case *test_case; 688 792 struct kunit_result_stats suite_stats = { 0 }; 689 793 struct kunit_result_stats total_stats = { 0 }; 690 - const void *curr_param; 691 794 692 795 /* Taint the kernel so we know we've run tests. */ 693 796 add_taint(TAINT_TEST, LOCKDEP_STILL_OK); ··· 806 703 807 704 kunit_print_suite_start(suite); 808 705 809 - kunit_suite_for_each_test_case(suite, test_case) { 810 - struct kunit test = { .param_value = NULL, .param_index = 0 }; 811 - struct kunit_result_stats param_stats = { 0 }; 812 - 813 - kunit_init_test(&test, test_case->name, test_case->log); 814 - if (test_case->status == KUNIT_SKIPPED) { 815 - /* Test marked as skip */ 816 - test.status = KUNIT_SKIPPED; 817 - kunit_update_stats(&param_stats, test.status); 818 - } else if (!test_case->generate_params) { 819 - /* Non-parameterised test. */ 820 - test_case->status = KUNIT_SKIPPED; 821 - kunit_run_case_catch_errors(suite, test_case, &test); 822 - kunit_update_stats(&param_stats, test.status); 823 - } else { 824 - kunit_init_parent_param_test(test_case, &test); 825 - if (test_case->status == KUNIT_FAILURE) { 826 - kunit_update_stats(&param_stats, test.status); 827 - goto test_case_end; 828 - } 829 - /* Get initial param. */ 830 - param_desc[0] = '\0'; 831 - /* TODO: Make generate_params try-catch */ 832 - curr_param = test_case->generate_params(&test, NULL, param_desc); 833 - test_case->status = KUNIT_SKIPPED; 834 - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT 835 - "KTAP version 1\n"); 836 - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT 837 - "# Subtest: %s", test_case->name); 838 - if (test.params_array.params && 839 - test_case->generate_params == kunit_array_gen_params) { 840 - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT 841 - KUNIT_SUBTEST_INDENT "1..%zd\n", 842 - test.params_array.num_params); 843 - } 844 - 845 - while (curr_param) { 846 - struct kunit param_test = { 847 - .param_value = curr_param, 848 - .param_index = ++test.param_index, 849 - .parent = &test, 850 - }; 851 - kunit_init_test(&param_test, test_case->name, NULL); 852 - param_test.log = test_case->log; 853 - kunit_run_case_catch_errors(suite, test_case, &param_test); 854 - 855 - if (param_desc[0] == '\0') { 856 - snprintf(param_desc, sizeof(param_desc), 857 - "param-%d", param_test.param_index); 858 - } 859 - 860 - kunit_print_ok_not_ok(&param_test, KUNIT_LEVEL_CASE_PARAM, 861 - param_test.status, 862 - param_test.param_index, 863 - param_desc, 864 - param_test.status_comment); 865 - 866 - kunit_update_stats(&param_stats, param_test.status); 867 - 868 - /* Get next param. */ 869 - param_desc[0] = '\0'; 870 - curr_param = test_case->generate_params(&test, curr_param, 871 - param_desc); 872 - } 873 - /* 874 - * TODO: Put into a try catch. Since we don't need suite->exit 875 - * for it we can't reuse kunit_try_run_cleanup for this yet. 876 - */ 877 - if (test_case->param_exit) 878 - test_case->param_exit(&test); 879 - /* TODO: Put this kunit_cleanup into a try-catch. */ 880 - kunit_cleanup(&test); 881 - } 882 - test_case_end: 883 - kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE); 884 - 885 - kunit_print_test_stats(&test, param_stats); 886 - 887 - kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status, 888 - kunit_test_case_num(suite, test_case), 889 - test_case->name, 890 - test.status_comment); 891 - 892 - kunit_update_stats(&suite_stats, test_case->status); 893 - kunit_accumulate_stats(&total_stats, param_stats); 894 - } 706 + kunit_suite_for_each_test_case(suite, test_case) 707 + kunit_run_one_test(suite, test_case, &suite_stats, &total_stats); 895 708 896 709 if (suite->suite_exit) 897 710 suite->suite_exit(suite); 898 711 899 - kunit_print_suite_stats(suite, suite_stats, total_stats); 712 + kunit_print_suite_stats(suite, &suite_stats, &total_stats); 900 713 suite_end: 901 714 kunit_print_suite_end(suite); 902 715