From patchwork Fri Sep 8 10:44:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377342 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 07730EE57EF for ; Fri, 8 Sep 2023 10:46:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7733210E896; Fri, 8 Sep 2023 10:46:32 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 120AC10E896; Fri, 8 Sep 2023 10:46:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694169991; x=1725705991; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hacE+i7chgQ9114zsM+ng4i72J6Nk9+HDDsyzr7orsU=; b=XKeDfeRnPKdkzxUrQm/j6zZdSHskSRNduIZeWa1wrTLMjUJIvdTe7YZD S4SUZ7zGNviFyLTXQNTDYPOldzYMl7+Zi2Awtxp+fZ2YXVLFCWPLNhgxB E0x1NHX83Y5yTvB0jjbJ3rltTIrqadfkF9WdLvdj0M0N0R/Ey+1dF4UpD NKRmB6mtf6nxbDoybMhVtJT+w+GiS4UqLO9Zv0P8qPvt4hTGXFHCmJ1c9 1GxPXt0oDwSnrtRS+YAD4wiY8vK5itX8A66uNH8nw61lUZUtucY7F4Ycb Mcb3HkkVUJfKSs5shJc1ERAIAdjnvk2ybcRwYJw1IFX2yAlxs3jMPfTpw w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922553" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922553" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531547" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531547" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:26 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:40 +0200 Message-ID: <20230908104438.125454-20-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 01/17] lib/kunit: Drop unused file stream X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" In the process of reviewing patches that introduced kunit support, I asked once if we could use line buffered input instead of explicitly looking for newlines in KTAP data. While my idea was wrong because reading raw data from /dev/kmsg already returns full log records that always end with a newline, conversion of /dev/kmsg file descriptor to a file stream with freopen() was added to the code. However, that file stream has never been used for line buffered input. While the file stream is passed to functions that actually read the data, there it is converted back to a file descriptor with fileno() and the data is read with read(). Drop the unnecessary conversions and teach functions to accept and process just the file descriptor of /dev/kmsg. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 12 +--------- lib/igt_ktap.c | 62 +++++++++++++++++++++++--------------------------- lib/igt_ktap.h | 2 +- 3 files changed, 31 insertions(+), 45 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 6205871791..97667a896f 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -758,7 +758,6 @@ static void __igt_kunit(const char *module_name, const char *opts) { struct igt_ktest tst; struct kmod_module *kunit_kmod; - FILE *f; bool is_builtin; int ret; struct ktap_test_results *results; @@ -774,7 +773,6 @@ static void __igt_kunit(const char *module_name, const char *opts) if (igt_ktest_begin(&tst) != 0) { igt_warn("Unable to begin ktest for %s\n", module_name); - igt_ktest_fini(&tst); igt_fail(IGT_EXIT_ABORT); } @@ -791,14 +789,6 @@ static void __igt_kunit(const char *module_name, const char *opts) goto unload; } - f = fdopen(tst.kmsg, "r"); - - if (f == NULL) { - igt_warn("Could not turn /dev/kmsg file descriptor into a FILE pointer\n"); - fail = true; - goto unload; - } - /* The KUnit module is required for running any KUnit tests */ ret = igt_kmod_load("kunit", NULL); if (ret) { @@ -814,7 +804,7 @@ static void __igt_kunit(const char *module_name, const char *opts) is_builtin = kmod_module_get_initstate(kunit_kmod) == KMOD_MODULE_BUILTIN; - results = ktap_parser_start(f, is_builtin); + results = ktap_parser_start(tst.kmsg, is_builtin); ret = igt_kmod_load(module_name, opts); if (ret) { diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index ecdcb8d83d..123a40d183 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -16,7 +16,7 @@ #define DELIMITER "-" struct ktap_parser_args { - FILE *fp; + int fd; bool is_builtin; volatile bool is_running; int ret; @@ -24,7 +24,7 @@ struct ktap_parser_args { static struct ktap_test_results results; -static int log_to_end(enum igt_log_level level, FILE *f, +static int log_to_end(enum igt_log_level level, int fd, char *record, const char *format, ...) __attribute__((format(printf, 4, 5))); /** @@ -39,12 +39,11 @@ static int log_to_end(enum igt_log_level level, FILE *f, * * Returns: 0 for success, or -2 if there's an error reading from the file */ -static int log_to_end(enum igt_log_level level, FILE *f, +static int log_to_end(enum igt_log_level level, int fd, char *record, const char *format, ...) { va_list args; const char *lend; - int f_fd = fileno(f); /* Cutoff after newline character, in order to not display garbage */ char *cutoff = strchr(record, '\n'); @@ -61,7 +60,7 @@ static int log_to_end(enum igt_log_level level, FILE *f, while (*lend == '\0') { igt_log(IGT_LOG_DOMAIN, level, "%s", record); - while (read(f_fd, record, BUF_LEN) < 0) { + while (read(fd, record, BUF_LEN) < 0) { if (!READ_ONCE(ktap_args.is_running)) { igt_warn("ktap parser stopped\n"); return -2; @@ -157,8 +156,8 @@ static int tap_version_present(char* record, bool print_info) /** * find_next_tap_subtest: - * @fp: FILE pointer - * @record: buffer used to read fp + * @fd: file descriptor + * @record: buffer used to read fd * @is_builtin: whether KUnit is built-in or not * * Returns: @@ -167,11 +166,10 @@ static int tap_version_present(char* record, bool print_info) * -2 if there are problems while reading the file. * any other value corresponds to the amount of cases of the next (sub)test */ -static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool is_builtin) +static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_builtin) { const char *test_lookup_str, *subtest_lookup_str, *name_rptr; long test_count; - int fp_fd = fileno(fp); char *cutoff; test_name[0] = '\0'; @@ -184,7 +182,7 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i return -1; if (is_builtin) { - while (read(fp_fd, record, BUF_LEN) < 0) { + while (read(fd, record, BUF_LEN) < 0) { if (!READ_ONCE(ktap_args.is_running)) { igt_warn("ktap parser stopped\n"); return -2; @@ -228,7 +226,7 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i if (cutoff) cutoff[0] = '\0'; - while (read(fp_fd, record, BUF_LEN) < 0) { + while (read(fd, record, BUF_LEN) < 0) { if (!READ_ONCE(ktap_args.is_running)) { igt_warn("ktap parser stopped\n"); return -2; @@ -265,7 +263,7 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i igt_info("Missing test count\n"); if (test_name[0] == '\0') return 0; - if (log_to_end(IGT_LOG_INFO, fp, record, + if (log_to_end(IGT_LOG_INFO, fd, record, "Running some tests in: %s\n", test_name) < 0) return -2; @@ -275,7 +273,7 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i return 0; } - if (log_to_end(IGT_LOG_INFO, fp, record, + if (log_to_end(IGT_LOG_INFO, fd, record, "Executing %ld tests in: %s\n", test_count, test_name) < 0) return -2; @@ -285,8 +283,8 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i /** * parse_kmsg_for_tap: - * @fp: FILE pointer - * @record: buffer used to read fp + * @fd: file descriptor + * @record: buffer used to read fd * @test_name: buffer to store the test name * * Returns: @@ -295,7 +293,7 @@ static int find_next_tap_subtest(FILE *fp, char *record, char *test_name, bool i * -1 if a test failed * -2 if there are problems reading the file */ -static int parse_kmsg_for_tap(FILE *fp, char *record, char *test_name) +static int parse_kmsg_for_tap(int fd, char *record, char *test_name) { const char *lstart, *ok_lookup_str, *nok_lookup_str, *ok_rptr, *nok_rptr, *comment_start, *value_parse_start; @@ -324,7 +322,7 @@ static int parse_kmsg_for_tap(FILE *fp, char *record, char *test_name) while (!isspace(*test_name_end)) test_name_end++; *test_name_end = '\0'; - if (log_to_end(IGT_LOG_WARN, fp, record, + if (log_to_end(IGT_LOG_WARN, fd, record, "%s", lstart) < 0) return -2; return -1; @@ -338,7 +336,7 @@ static int parse_kmsg_for_tap(FILE *fp, char *record, char *test_name) value_parse_start = comment_start; if (lookup_value(value_parse_start, "fail: ") > 0) { - if (log_to_end(IGT_LOG_WARN, fp, record, + if (log_to_end(IGT_LOG_WARN, fd, record, "%s", lstart) < 0) return -2; return -1; @@ -362,7 +360,7 @@ static int parse_kmsg_for_tap(FILE *fp, char *record, char *test_name) /** * parse_tap_level: - * @fp: FILE pointer + * @fd: file descriptor * @base_test_name: test_name from upper recursion level * @test_count: test_count of this level * @failed_tests: top level failed_tests pointer @@ -373,10 +371,9 @@ static int parse_kmsg_for_tap(FILE *fp, char *record, char *test_name) * 0 if succeded * -1 if error occurred */ -static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool *failed_tests, +static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *failed_tests, bool *found_tests, bool is_builtin) { - int fp_fd = fileno(fp); char record[BUF_LEN + 1]; struct ktap_test_results_element *r, *temp; int internal_test_count; @@ -384,7 +381,7 @@ static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool char base_test_name_for_next_level[BUF_LEN + 1]; for (int i = 0; i < test_count; i++) { - while (read(fp_fd, record, BUF_LEN) < 0) { + while (read(fd, record, BUF_LEN) < 0) { if (!READ_ONCE(ktap_args.is_running)) { igt_warn("ktap parser stopped\n"); return -1; @@ -409,7 +406,7 @@ static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool /* Sublevel found */ if (tap_version_present(record, false)) { - internal_test_count = find_next_tap_subtest(fp, record, test_name, + internal_test_count = find_next_tap_subtest(fd, record, test_name, is_builtin); switch (internal_test_count) { case -2: @@ -433,7 +430,7 @@ static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool memcpy(base_test_name_for_next_level + strlen(base_test_name_for_next_level), test_name, BUF_LEN - strlen(base_test_name_for_next_level)); - if (parse_tap_level(fp, base_test_name_for_next_level, + if (parse_tap_level(fd, base_test_name_for_next_level, internal_test_count, failed_tests, found_tests, is_builtin) == -1) return -1; @@ -441,7 +438,7 @@ static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool } } - switch (parse_kmsg_for_tap(fp, record, test_name)) { + switch (parse_kmsg_for_tap(fd, record, test_name)) { case -2: return -1; case -1: @@ -516,8 +513,7 @@ static int parse_tap_level(FILE *fp, char *base_test_name, int test_count, bool */ void *igt_ktap_parser(void *unused) { - FILE *fp = ktap_args.fp; - int fp_fd = fileno(fp); + int fd = ktap_args.fd; char record[BUF_LEN + 1]; bool is_builtin = ktap_args.is_builtin; char test_name[BUF_LEN + 1]; @@ -534,7 +530,7 @@ igt_ktap_parser_start: test_name[0] = '\0'; test_name[BUF_LEN] = '\0'; - while (read(fp_fd, record, BUF_LEN) < 0) { + while (read(fd, record, BUF_LEN) < 0) { if (!READ_ONCE(ktap_args.is_running)) { igt_warn("ktap parser stopped\n"); goto igt_ktap_parser_end; @@ -553,7 +549,7 @@ igt_ktap_parser_start: } } - test_count = find_next_tap_subtest(fp, record, test_name, is_builtin); + test_count = find_next_tap_subtest(fd, record, test_name, is_builtin); switch (test_count) { case -2: @@ -569,7 +565,7 @@ igt_ktap_parser_start: default: found_tests = true; - if (parse_tap_level(fp, test_name, test_count, &failed_tests, &found_tests, + if (parse_tap_level(fd, test_name, test_count, &failed_tests, &found_tests, is_builtin) == -1) goto igt_ktap_parser_end; @@ -578,7 +574,7 @@ igt_ktap_parser_start: /* Parse topmost level */ test_name[0] = '\0'; - parse_tap_level(fp, test_name, test_count, &failed_tests, &found_tests, is_builtin); + parse_tap_level(fd, test_name, test_count, &failed_tests, &found_tests, is_builtin); igt_ktap_parser_end: results.still_running = false; @@ -593,13 +589,13 @@ igt_ktap_parser_end: static pthread_t ktap_parser_thread; -struct ktap_test_results *ktap_parser_start(FILE *fp, bool is_builtin) +struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) { results.head = NULL; pthread_mutex_init(&results.mutex, NULL); results.still_running = true; - ktap_args.fp = fp; + ktap_args.fd = fd; ktap_args.is_builtin = is_builtin; ktap_args.is_running = true; pthread_create(&ktap_parser_thread, NULL, igt_ktap_parser, NULL); diff --git a/lib/igt_ktap.h b/lib/igt_ktap.h index 34fe095720..ea57c2bb9b 100644 --- a/lib/igt_ktap.h +++ b/lib/igt_ktap.h @@ -44,7 +44,7 @@ struct ktap_test_results { -struct ktap_test_results *ktap_parser_start(FILE *fp, bool is_builtin); +struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin); int ktap_parser_stop(void); #endif /* IGT_KTAP_H */ From patchwork Fri Sep 8 10:44:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377343 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 55581EE57F1 for ; Fri, 8 Sep 2023 10:46:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CFC9410E899; Fri, 8 Sep 2023 10:46:34 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 349AC10E899; Fri, 8 Sep 2023 10:46:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694169993; x=1725705993; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NgGrmVyyZfFDm3AIzeCAssCCd7sLa2xWlFx06MXCHiE=; b=RIE5gMP2AxvRjgv9b+uXeq8tDA+xXkUk3cVbIBFSHPJZB7V4x3mcWQo5 PsViB+bVpY0qkt/MEXres7FeCslzw7ETNbTBhfE3v58XUaL/a57G3rTsA JrtASBORIkkoSAMBD7m6T2KH75IEzVR0CpRXAPhXc4sOLyadJt7tkUnT0 eedg9iwlekQ0nZq2SDN1WqMb4ro8vSOct5/t2Kz+ocLbgqMqlEMQIllwo 07xlZxSlm9b8gwOVos6Qu0ou7csXoYIKlGV+qyrJnHFqtGIJyuSc08ikF 5Vq+MAFmvkvuOawukoCF8MozxwsOEhiCTIq+ZZHwgHcoIYS5ckfl1JBqn w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922558" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922558" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531551" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531551" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:31 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:41 +0200 Message-ID: <20230908104438.125454-21-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 02/17] lib/kunit: Stop loading kunit module explicitly X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Since kmod functions we use for module loading can process module dependencies, there is no need to load the "kunit" module explicitly before loading a kunit test module. For the same reason we already don't unload the "kunit" module explicitly on cleanup. Drop the unnecessary operation. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 97667a896f..faf31afabc 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -789,12 +789,6 @@ static void __igt_kunit(const char *module_name, const char *opts) goto unload; } - /* The KUnit module is required for running any KUnit tests */ - ret = igt_kmod_load("kunit", NULL); - if (ret) { - skip = ret; - goto unload; - } ret = kmod_module_new_from_name(kmod_ctx(), "kunit", &kunit_kmod); if (ret) { igt_warn("Unable to load KUnit\n"); From patchwork Fri Sep 8 10:44:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377344 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E1ACEEE57F1 for ; Fri, 8 Sep 2023 10:46:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 23ED010E89E; Fri, 8 Sep 2023 10:46:37 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6852110E89B; Fri, 8 Sep 2023 10:46:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694169995; x=1725705995; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4ALvskPNi3LaMw5KVy7vYqgxxd2v3zPfVa4OMNirJ8E=; b=X/TKKAZNoyulFZtfOlNvrUVXc0Y5rGXcunWZK2BsHl1IyIiSe7ENjKI9 5sch1cNqaNIKDqNwkPMq+Il6XJw8vBQusehZlbpPsWPRSByTrf9zFure2 EuBKMXq052Tf58UxZMAZ8TYKD9d1oEsMDH2q4bP9vF4bNjwI4kfgjJvte hpbHKsKNV2FnrB/E8blGga634ulWewU55oEA44wdK1/fmKOPh5pongsNH xScSTtdHYLMysZQndnBkd7/PUG/gbc0UyNpdvd6DWDlb4WygkYugwitT1 6ZNbi4OWRHXWSKg3XrToVF/njZdQvivD/KgZ8by8bQ56SXYT93hyuhLdt A==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922567" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922567" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531554" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531554" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:33 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:42 +0200 Message-ID: <20230908104438.125454-22-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 03/17] lib/kunit: Fix struct kmod_module kunit_kmod not freed X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" We obtain a kmod_module structure for kunit module in order to check if it is modular or built-in, then we never release that structure. Fix it. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index faf31afabc..34ddec3fad 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -797,6 +797,7 @@ static void __igt_kunit(const char *module_name, const char *opts) } is_builtin = kmod_module_get_initstate(kunit_kmod) == KMOD_MODULE_BUILTIN; + kmod_module_unref(kunit_kmod); results = ktap_parser_start(tst.kmsg, is_builtin); From patchwork Fri Sep 8 10:44:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA9F1EE57EF for ; Fri, 8 Sep 2023 10:46:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CD45010E8A3; Fri, 8 Sep 2023 10:46:40 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 90C4710E89F; Fri, 8 Sep 2023 10:46:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694169997; x=1725705997; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r+IHRzp6K/Mi2Qdb1+eIJA15NKdIDNp1VFDAPNtiAi0=; b=PyD1WBdYy37oYB5kAvnXjzWb7VpDKOXUaHcT6djUJ4ryyBYa/BgIiidi lx3khu7l9vK8ObzVolzsE6nH95E8X5kAKvPd+FpE7gyqrALHS1NwzIXK8 SHmLoROiEiF3O0yP2bfAKPJQp3PtoaHv41E1s8AA2iyKLAe30StX6XUNA HZiwJIYoqNfjfmqXhALUjzhF4l3hKAAQ2Sb3lr0E+tMw7eStpGC2TpOXR qKXDfbsrH3LfKGssOQjac5omemV3FS/Nng8R/Y73f7c3zzN0bZSvwwX5a SQRm2xznfXdyjZOpd9LnNNOOG50Ne6hcnpU7kzB8yw7tvjabN8XR6sPo0 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922574" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922574" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531561" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531561" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:35 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:43 +0200 Message-ID: <20230908104438.125454-23-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 04/17] lib/kunit: Optimize calls to igt_success/skip/fail() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Calling igt_success() explicitly at the end of subtest body is not needed. Other calls to igt_success() can be usually avoided by inverting test result checks. Optimize the code that now calls igt_success(). Moreover, using more advanced variants of igt_skip() and igt_fail() where applicable makes the code more compact. Go for it. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 34ddec3fad..1d1cd51170 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -814,12 +814,8 @@ static void __igt_kunit(const char *module_name, const char *opts) if (READ_ONCE(results->head) != NULL) { pthread_mutex_lock(&results->mutex); - igt_dynamic(results->head->test_name) { - if (READ_ONCE(results->head->passed)) - igt_success(); - else - igt_fail(IGT_EXIT_FAILURE); - } + igt_dynamic(results->head->test_name) + igt_assert(READ_ONCE(results->head->passed)); temp = results->head; results->head = results->head->next; @@ -834,8 +830,7 @@ unload: igt_ktest_fini(&tst); - if (skip) - igt_skip("Skipping test, as probing KUnit module returned %d", skip); + igt_skip_on_f(skip, "Skipping test, as probing KUnit module failed\n"); if (fail) igt_fail(IGT_EXIT_ABORT); @@ -844,9 +839,6 @@ unload: if (ret != 0) igt_fail(IGT_EXIT_ABORT); - - if (ret == 0) - igt_success(); } void igt_kunit(const char *module_name, const char *name, const char *opts) From patchwork Fri Sep 8 10:44:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377346 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A740CEE57F1 for ; Fri, 8 Sep 2023 10:46:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1A95410E88E; Fri, 8 Sep 2023 10:46:42 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id C15D910E8A3; Fri, 8 Sep 2023 10:46:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694169999; x=1725705999; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zrozHbnIxquxu6XJU7JLHVUz1aTSQeokCb3A9rWaclw=; b=WaRlZFNhNLvRnB4SycF+TbwJ3sxgOoExg/VmvFUxbpxH6EuYo6yW+Gyd bz7W+J5qHcs97zj4aTpFMtu8WcaNfVXPfa+aSZfwOnl9+lNKsSISAbbW7 mYt1ADFsPz9/1u70QZUDizhi5nKnxuOafpUqNvJm9K4jyBRbfLu5X/duI 1auanwkZfoCqXWpclJ606GiwP4So93nXwYR7Zj1K8nq9JyY7CVIovxKNE Utmngf6F63SweC5Rl0cIN8p8du2XSZy6SQggsTftlReLwu+fqid8HmoTS nI0zuT9FI5NBQvHDQSxsJZ25aIlP/3dioNs30hj8tGjcSn8CrON+FkAgh Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922582" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922582" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531569" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531569" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:37 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:44 +0200 Message-ID: <20230908104438.125454-24-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 05/17] lib/kunit: Fix illegal igt_fail() calls inside subtest body X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" In a body of a subtest with dynamic sub-subtests, it is illegal to call igt_fail() and its variants from outside of a dynamic sub-subtest body. On the other hand, it is perfectly legal to call either igt_skip() and friends or __igt_abort() or its variant from there. In the current implementation of igt_kunit(), there are several places where igt_fail() is called despite being illegal. Moreover, it is called with IGT_EXIT_ABORT as an argument with no good reason for using such aggressive method that forces CI to trigger system reboot (in most cases igt_runner can decide if abort is required). Follow igt_kselftests() pattern more closely, where similar setup and cleanup operations are performed but their potential errors are processed in a more friendly way. Move common cleanup and their corresponding setup steps out of the subtest body. Place the latter as requirements in a preceding igt_fixture section. Replace remaining illegal igt_fail() calls with more friendly skips. Let igt_runner decide if abort is needed. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 75 +++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 53 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 1d1cd51170..78b8eb8f53 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -754,59 +754,27 @@ void igt_kselftest_get_tests(struct kmod_module *kmod, * * Returns: IGT default codes */ -static void __igt_kunit(const char *module_name, const char *opts) +static void __igt_kunit(struct igt_ktest *tst, const char *opts) { - struct igt_ktest tst; struct kmod_module *kunit_kmod; bool is_builtin; int ret; struct ktap_test_results *results; struct ktap_test_results_element *temp; - int skip = 0; - bool fail = false; - - /* get normalized module name */ - if (igt_ktest_init(&tst, module_name) != 0) { - igt_warn("Unable to initialize ktest for %s\n", module_name); - igt_fail(IGT_EXIT_ABORT); - } - - if (igt_ktest_begin(&tst) != 0) { - igt_warn("Unable to begin ktest for %s\n", module_name); - igt_ktest_fini(&tst); - igt_fail(IGT_EXIT_ABORT); - } - if (tst.kmsg < 0) { - igt_warn("Could not open /dev/kmsg\n"); - fail = true; - goto unload; - } + igt_skip_on_f(tst->kmsg < 0, "Could not open /dev/kmsg\n"); - if (lseek(tst.kmsg, 0, SEEK_END)) { - igt_warn("Could not seek the end of /dev/kmsg\n"); - fail = true; - goto unload; - } - - ret = kmod_module_new_from_name(kmod_ctx(), "kunit", &kunit_kmod); - if (ret) { - igt_warn("Unable to load KUnit\n"); - skip = ret; - goto unload; - } + igt_skip_on(lseek(tst->kmsg, 0, SEEK_END) < 0); + igt_skip_on(kmod_module_new_from_name(kmod_ctx(), "kunit", &kunit_kmod)); is_builtin = kmod_module_get_initstate(kunit_kmod) == KMOD_MODULE_BUILTIN; kmod_module_unref(kunit_kmod); - results = ktap_parser_start(tst.kmsg, is_builtin); + results = ktap_parser_start(tst->kmsg, is_builtin); - ret = igt_kmod_load(module_name, opts); - if (ret) { - skip = ret; - igt_warn("Unable to load %s module\n", module_name); - ret = ktap_parser_stop(); - goto unload; + if (igt_debug_on(igt_kmod_load(tst->module_name, opts) < 0)) { + igt_ignore_warn(ktap_parser_stop()); + igt_skip("Unable to load %s module\n", tst->module_name); } while (READ_ONCE(results->still_running) || READ_ONCE(results->head) != NULL) @@ -825,24 +793,21 @@ static void __igt_kunit(const char *module_name, const char *opts) } } -unload: - igt_ktest_end(&tst); - - igt_ktest_fini(&tst); - - igt_skip_on_f(skip, "Skipping test, as probing KUnit module failed\n"); - - if (fail) - igt_fail(IGT_EXIT_ABORT); - ret = ktap_parser_stop(); - if (ret != 0) - igt_fail(IGT_EXIT_ABORT); + igt_skip_on_f(ret, "KTAP parser failed\n"); } void igt_kunit(const char *module_name, const char *name, const char *opts) { + struct igt_ktest tst; + + if (igt_ktest_init(&tst, module_name) != 0) + return; + + igt_fixture + igt_require(igt_ktest_begin(&tst) == 0); + /* * We need to use igt_subtest here, as otherwise it may crash with: * skipping is allowed only in fixtures, subtests or igt_simple_main @@ -854,7 +819,11 @@ void igt_kunit(const char *module_name, const char *name, const char *opts) name = module_name; igt_subtest_with_dynamic(name) - __igt_kunit(module_name, opts); + __igt_kunit(&tst, opts); + + igt_ktest_end(&tst); + + igt_ktest_fini(&tst); } static int open_parameters(const char *module_name) From patchwork Fri Sep 8 10:44:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377347 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 74CC3EE57F3 for ; Fri, 8 Sep 2023 10:46:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BFE0F10E8A6; Fri, 8 Sep 2023 10:46:43 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 416A610E8A4; Fri, 8 Sep 2023 10:46:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170002; x=1725706002; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DuR9KvcoUVDYrg3SuqqMkjTr0aU3slLY33Dj+Euc05E=; b=oEnKMx7dzpihdTtuXBiNpFEczoIYtpnB6WOSmBtxdBRfCwJ6QgyFLkhF omPf4XNMupSO1CJuJ2901er5JmLcx0moWdxJ/qFGAGUvaLfijBU0u2sE1 21L1+lfmGMu06TYRGQCCgRzRKrGTU32l/KcVtbBl5fr3QS/9XDA+p6QY/ SEhtyIpKjoq26KEncYS6B7BhvyeY/4zy8tKwn0bFZQC26QZlplPNFZIbE 4lSDzK1vofHpA0IxCSEbjX8+hv67raVK0kRUYSUFOxKcxp6svg5X8a+z1 soaJ2ToATZcQlv36JZjRoBxunnY3VW/UJZhomRtA1qKHNu3ChEWQuy0Za A==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922598" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922598" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531582" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531582" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:39 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:45 +0200 Message-ID: <20230908104438.125454-25-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 06/17] lib/ktap: Make sure we fail on premature cancel X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" After loading a kunit test module that executes some kunit test cases, we evaluate overall result of an IGT subtest that corresponds to that module based on an error code returned by kunit_parser_stop() helper, obtained from a .ret field of a ktap_args structure. That code is now assigned to that structure field right before completion of the KTAP parser thread start routine. If the thread is canceled for some reason then the return code will be undefined. Initialize the return code on KTAP parser startup with a value that indicates a failure, then change it to success when so indicated by result of KTAP parsing. Signed-off-by: Janusz Krzysztofik --- lib/igt_ktap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 123a40d183..84fb13218f 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -579,9 +579,7 @@ igt_ktap_parser_start: igt_ktap_parser_end: results.still_running = false; - if (failed_tests || !found_tests) - ktap_args.ret = IGT_EXIT_FAILURE; - else + if (found_tests && !failed_tests) ktap_args.ret = IGT_EXIT_SUCCESS; return NULL; @@ -598,6 +596,7 @@ struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) ktap_args.fd = fd; ktap_args.is_builtin = is_builtin; ktap_args.is_running = true; + ktap_args.ret = IGT_EXIT_FAILURE; pthread_create(&ktap_parser_thread, NULL, igt_ktap_parser, NULL); return &results; From patchwork Fri Sep 8 10:44:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377348 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 61057EE57EF for ; Fri, 8 Sep 2023 10:46:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8E76710E0A6; Fri, 8 Sep 2023 10:46:54 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 34C5610E0A6; Fri, 8 Sep 2023 10:46:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170012; x=1725706012; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Kqg/JgU4K6vqvSdGeeC7sS3V2UoYHKYoEhyc3p8kMEI=; b=WUPtwolCO92i8324mAnPsurLPFgQMxQNDqlbor9V26aSp5IBs30IZ2wh TKfIxKAZuRYoir+hdcUimOmUdPZqD29AW/iKfUXMCaQeIPYVI4i5s+6mF xNUt/zSTrmrFbJfxK7su0I2tyE0gFlK/KqxM9j82LYFwhD/pPgSM2mkbJ c6TXqrLJEh6Q2S4bEMNx2Rg7nffxa4DljU/9aIuyTf9EZ7Fxg7Hw5sWKU eVWJcgffbXcnETg3pX0XaxhKHPuUF/6bSl2T3Jwy/qHBUgl++dgzg39a7 EpRl+oILo/knkT8QvWcNo81KGOheXdrtde6j+BzrBJChq29KxL2eS3Vx8 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922624" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922624" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531589" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531589" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:42 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:46 +0200 Message-ID: <20230908104438.125454-26-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 07/17] lib/ktap: Don't ignore interrupt signals X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" While reading KTAP data from /dev/kmsg we now ignore interrupt signals that may occur during read() and we continue reading the data. No explanation has been provided on what that could be needed for. Always return with an error code to the caller when read() fails with errno == EINTR, so igt_runner has no problems with killing us promptly on timeout. Signed-off-by: Janusz Krzysztofik --- lib/igt_ktap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 84fb13218f..3cfb55ec97 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -67,7 +67,7 @@ static int log_to_end(enum igt_log_level level, int fd, } if (errno == EINTR) - continue; + return -2; if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); @@ -189,7 +189,7 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ } if (errno == EINTR) - continue; + return -2; if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); @@ -233,7 +233,7 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ } if (errno == EINTR) - continue; + return -2; if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); @@ -388,7 +388,7 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f } if (errno == EINTR) - continue; + return -1; if (errno == EAGAIN) /* No records available */ @@ -541,7 +541,7 @@ igt_ktap_parser_start: continue; if (errno == EINTR) - continue; + goto igt_ktap_parser_end; if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); From patchwork Fri Sep 8 10:44:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377350 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 82A52EE57F3 for ; Fri, 8 Sep 2023 10:46:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8E53B10E8A0; Fri, 8 Sep 2023 10:46:55 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 867BA10E89A; Fri, 8 Sep 2023 10:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170012; x=1725706012; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nXREkvPA82Us23UqpnMo3Rm7aWMcQPg5Crt1sUMTIM4=; b=D2brvC/t/KQm+xAoJEB8uN3On8QObD6R5XlYS8Nwec46NrkEzqoDvlBt MFArXE4xsOIwP5XLerB//dyTbUAZ6TilIQjASv0RAycbP+Jg3eUPOUa2g PaQB4XqWpsTdYT+7/dCs2VFd1riZdfgNcYtIhId6pqyiSoUKrXM4KOenS DG9T1qUhqEK9mOR1JVsmTQrnKX2QaZ06OBcb4Oqh4g3F7u7LbBuPNHeTV S9r+GduvPFHwMee0zTDdxiCn51dGwMexTKSH6mBhhv6R/ZM4SSFp2MCAt 1RqqUS/pKc+K+c0XBaQRBQL/cvDqvDpjRy1QCofngoI/ZjgzOrr56CZji w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922636" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922636" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531596" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531596" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:44 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:47 +0200 Message-ID: <20230908104438.125454-27-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 08/17] lib/kunit: Cancel KTP parser on module load failure X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" For our KTAP parser to be running in parallel with kunit test module loading, we now start it in a separate thread before we load the module. If the module loading fails then we join the KTAP parser thread right after that failure. If the KTAP thread sleeps for some reason then we can fail to break the test immediately. Cancel the KTAP parser thread right after module load error and before joining it. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 1 + lib/igt_ktap.c | 6 ++++++ lib/igt_ktap.h | 1 + 3 files changed, 8 insertions(+) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 78b8eb8f53..fb0bd21ee5 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -773,6 +773,7 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) results = ktap_parser_start(tst->kmsg, is_builtin); if (igt_debug_on(igt_kmod_load(tst->module_name, opts) < 0)) { + ktap_parser_cancel(); igt_ignore_warn(ktap_parser_stop()); igt_skip("Unable to load %s module\n", tst->module_name); } diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 3cfb55ec97..1e75b2ec23 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -602,6 +602,12 @@ struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) return &results; } +void ktap_parser_cancel(void) +{ + ktap_args.is_running = false; + pthread_cancel(ktap_parser_thread); +} + int ktap_parser_stop(void) { ktap_args.is_running = false; diff --git a/lib/igt_ktap.h b/lib/igt_ktap.h index ea57c2bb9b..991800e912 100644 --- a/lib/igt_ktap.h +++ b/lib/igt_ktap.h @@ -45,6 +45,7 @@ struct ktap_test_results { struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin); +void ktap_parser_cancel(void); int ktap_parser_stop(void); #endif /* IGT_KTAP_H */ From patchwork Fri Sep 8 10:44:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377351 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 35097EE57F1 for ; Fri, 8 Sep 2023 10:46:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BFA4810E8A8; Fri, 8 Sep 2023 10:46:56 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id CB54B10E0A6; Fri, 8 Sep 2023 10:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170012; x=1725706012; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Iy4Wkm7BIqZQeR2Ce2G1c7URzd6FFKkhSvdr4zNM74I=; b=bVr9dKWES/+6Ipzw4Pp0K/eyk0AqMfBPXRBISxsFmjk+zH3wtQjf2vo0 SIMNP9a+oZKE9WjQ/MUNmUOw/dv4yEm0ksnIlbfKpy0YSKJ8f35vo6XNn tFT/sJU2rcdFYvk4gc++wp4Y/1pJI+wxyK/Zjy7VQAmbxubH8X74I79If HjynmPFVWTpCBWLy2i4pUK67VGBJfp1PGhb9VG6/uB5amgkY4cHpgj9f2 9J6MtbdhwqGnZtjQTwfeny8J9w8/lONKIGxWRCc1nsAbyJRh4prprW5EK Bo/7dkhLGh5SDl2xUbW96bSkHoySmUHZFsLS2ysZoURsKQEVNhE3ByWWK g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922643" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922643" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531604" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531604" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:47 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:48 +0200 Message-ID: <20230908104438.125454-28-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 09/17] lib/ktap: Drop is_running flag X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Since we now call pthread_cancel() when we want to stop KTAP parser before it completes, and we take care of returning failure in that case as a result of KTAP parsing, we no longer need to check a flag that indicates whether we should continue parsing or return a failure. Drop that flag. Signed-off-by: Janusz Krzysztofik --- lib/igt_ktap.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 1e75b2ec23..fe77b62680 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -18,7 +18,6 @@ struct ktap_parser_args { int fd; bool is_builtin; - volatile bool is_running; int ret; } ktap_args; @@ -61,11 +60,6 @@ static int log_to_end(enum igt_log_level level, int fd, igt_log(IGT_LOG_DOMAIN, level, "%s", record); while (read(fd, record, BUF_LEN) < 0) { - if (!READ_ONCE(ktap_args.is_running)) { - igt_warn("ktap parser stopped\n"); - return -2; - } - if (errno == EINTR) return -2; @@ -183,11 +177,6 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ if (is_builtin) { while (read(fd, record, BUF_LEN) < 0) { - if (!READ_ONCE(ktap_args.is_running)) { - igt_warn("ktap parser stopped\n"); - return -2; - } - if (errno == EINTR) return -2; @@ -227,11 +216,6 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ cutoff[0] = '\0'; while (read(fd, record, BUF_LEN) < 0) { - if (!READ_ONCE(ktap_args.is_running)) { - igt_warn("ktap parser stopped\n"); - return -2; - } - if (errno == EINTR) return -2; @@ -382,11 +366,6 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f for (int i = 0; i < test_count; i++) { while (read(fd, record, BUF_LEN) < 0) { - if (!READ_ONCE(ktap_args.is_running)) { - igt_warn("ktap parser stopped\n"); - return -1; - } - if (errno == EINTR) return -1; @@ -523,19 +502,11 @@ void *igt_ktap_parser(void *unused) failed_tests = false; found_tests = false; - if (!READ_ONCE(ktap_args.is_running)) - goto igt_ktap_parser_end; - igt_ktap_parser_start: test_name[0] = '\0'; test_name[BUF_LEN] = '\0'; while (read(fd, record, BUF_LEN) < 0) { - if (!READ_ONCE(ktap_args.is_running)) { - igt_warn("ktap parser stopped\n"); - goto igt_ktap_parser_end; - } - if (errno == EAGAIN) /* No records available */ continue; @@ -595,7 +566,6 @@ struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) ktap_args.fd = fd; ktap_args.is_builtin = is_builtin; - ktap_args.is_running = true; ktap_args.ret = IGT_EXIT_FAILURE; pthread_create(&ktap_parser_thread, NULL, igt_ktap_parser, NULL); @@ -604,13 +574,11 @@ struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) void ktap_parser_cancel(void) { - ktap_args.is_running = false; pthread_cancel(ktap_parser_thread); } int ktap_parser_stop(void) { - ktap_args.is_running = false; pthread_join(ktap_parser_thread, NULL); return ktap_args.ret; } From patchwork Fri Sep 8 10:44:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377349 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69B21EE57F4 for ; Fri, 8 Sep 2023 10:46:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 26E3310E89D; Fri, 8 Sep 2023 10:46:55 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id D744A10E89B; Fri, 8 Sep 2023 10:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170012; x=1725706012; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=55V6t5Ju+XFqIVVIYdnF7/ugUTSZtBAc94mjKus7wbw=; b=T61hGgB+k++QwBW7XtJjPVVpSEq9OMPuiobzJWu3wWWWaAnSiEvc8VN0 Xd9xoC2U4Tl32yjsbsw0SlnqvFAp/SwbXO7gGYRikxrANgOyje3Q/iqlR KvJ7yaglmoppLOUt/74IFBFETXPykLlsaej5QysTitxPYoKA9yfoCTAyl CBxZkKWCJA5KyebcvixMcgT2pcDYsY/8qdxhmzSbyB3uh7XwtAvvhXgQD syYcorZ9p6vVKvZ2ivjQOJhR3gOvwdt91Byn8cXuz9XCuKiN2OJcK7B3/ i5q3QB4lnm+yga5feN6m4PPM090Kn2wpLBDdwcu3QOhQz+0otTSxVKjui w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922646" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922646" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531610" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531610" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:49 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:49 +0200 Message-ID: <20230908104438.125454-29-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 10/17] lib/ktap: Read /dev/kmsg in blocking mode X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" We obtain KTAP report from /dev/kmsg. That file is now opened from igt_ktest_begin(), a function originally designed for i915 selftests and now reused with kunit tests. The original intention of opening that file was to dump kernel messages to stderr on selftest error. For that purpose, the file is now opened in non-blocking mode so we don't end up waiting for more kernel messages than already available. Since our ktap parser code reuses the file descriptor, we now have to loop over EAGAIN responses, waiting for more KTAP data. Since we have no sleeps inside those loops, extremely high CPU usage can be observed. Simplify reading KTAP reports by first switching the file descriptor back to blocking mode. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 7 ++++- lib/igt_ktap.c | 81 ++++++++++++++------------------------------------ 2 files changed, 28 insertions(+), 60 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index fb0bd21ee5..020df286b8 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "igt_aux.h" @@ -758,12 +759,16 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) { struct kmod_module *kunit_kmod; bool is_builtin; - int ret; struct ktap_test_results *results; struct ktap_test_results_element *temp; + int flags, ret; igt_skip_on_f(tst->kmsg < 0, "Could not open /dev/kmsg\n"); + flags = fcntl(tst->kmsg, F_GETFL, 0) & ~O_NONBLOCK; + igt_skip_on_f(fcntl(tst->kmsg, F_SETFL, flags) == -1, + "Could not set /dev/kmsg to blocking mode\n"); + igt_skip_on(lseek(tst->kmsg, 0, SEEK_END) < 0); igt_skip_on(kmod_module_new_from_name(kmod_ctx(), "kunit", &kunit_kmod)); diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index fe77b62680..165f6b2cce 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -59,20 +59,12 @@ static int log_to_end(enum igt_log_level level, int fd, while (*lend == '\0') { igt_log(IGT_LOG_DOMAIN, level, "%s", record); - while (read(fd, record, BUF_LEN) < 0) { - if (errno == EINTR) - return -2; - - if (errno == EPIPE) { + if (read(fd, record, BUF_LEN) < 0) { + if (errno == EPIPE) igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - return -2; - } + else if (errno != EINTR) + igt_warn("an error occurred while reading kmsg: %m\n"); - if (errno == EAGAIN) - /* No records available */ - continue; - - igt_warn("kmsg truncated: unknown error (%m)\n"); return -2; } @@ -176,20 +168,12 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ return -1; if (is_builtin) { - while (read(fd, record, BUF_LEN) < 0) { - if (errno == EINTR) - return -2; - - if (errno == EPIPE) { + if (read(fd, record, BUF_LEN) < 0) { + if (errno == EPIPE) igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - return -2; - } + else if (errno != EINTR) + igt_warn("an error occurred while reading kmsg: %m\n"); - if (errno == EAGAIN) - /* No records available */ - continue; - - igt_warn("kmsg truncated: unknown error (%m)\n"); return -2; } } @@ -215,20 +199,12 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ if (cutoff) cutoff[0] = '\0'; - while (read(fd, record, BUF_LEN) < 0) { - if (errno == EINTR) - return -2; - - if (errno == EPIPE) { + if (read(fd, record, BUF_LEN) < 0) { + if (errno == EPIPE) igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - return -2; - } + else if (errno != EINTR) + igt_warn("unknown error reading kmsg (%m)\n"); - if (errno == EAGAIN) - /* No records available */ - continue; - - igt_warn("kmsg truncated: unknown error (%m)\n"); return -2; } @@ -365,20 +341,12 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f char base_test_name_for_next_level[BUF_LEN + 1]; for (int i = 0; i < test_count; i++) { - while (read(fd, record, BUF_LEN) < 0) { - if (errno == EINTR) - return -1; - - if (errno == EAGAIN) - /* No records available */ - continue; - - if (errno == EPIPE) { + if (read(fd, record, BUF_LEN) < 0) { + if (errno == EPIPE) igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - return -1; - } + else if (errno != EINTR) + igt_warn("error reading kmsg (%m)\n"); - igt_warn("kmsg truncated: unknown error (%m)\n"); return -1; } @@ -506,18 +474,13 @@ igt_ktap_parser_start: test_name[0] = '\0'; test_name[BUF_LEN] = '\0'; - while (read(fd, record, BUF_LEN) < 0) { - if (errno == EAGAIN) - /* No records available */ - continue; - - if (errno == EINTR) - goto igt_ktap_parser_end; - - if (errno == EPIPE) { + if (read(fd, record, BUF_LEN) < 0) { + if (errno == EPIPE) igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - goto igt_ktap_parser_end; - } + else if (errno != EINTR) + igt_warn("error reading kmsg (%m)\n"); + + goto igt_ktap_parser_end; } test_count = find_next_tap_subtest(fd, record, test_name, is_builtin); From patchwork Fri Sep 8 10:44:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377352 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4EF61EE57EF for ; Fri, 8 Sep 2023 10:47:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 34B0510E8A7; Fri, 8 Sep 2023 10:46:57 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id E1D1310E0A6; Fri, 8 Sep 2023 10:46:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170014; x=1725706014; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7JwD+XeooPOPHuA1WH62ZC7XBAnCsiTezdkxLExk9wQ=; b=W7OTAeYufY95KzzGaja1LsNphm7qsFW4s7O6Q2k8n9AbJvFYIc4XE1Dw PphPU0S1gq6dJ+SZwB6az95A2yD2vQDBEfOPzN8L0aGtkbpAIgphpYmGq bd++DX8t7XT7/pQYZPzZZt9RfJ7SMClWRsN5ZhXOGtexcUD6Of9E11N/K Jynslr3BQEYQIFc3ge0uvaXEad2IU8fWlkV5dLuGBcba5IgOzkJI+3e6c od3eFscLDIHI8ni4CZwru51nKZfeW2+8Lg4IHQeKjifzcmu6ME+z6SOIW kA7uVuxZYo7H+4bK2ZPvsDGc8y9m/2/t7GLy8I5S596KYlvkJMPMajkTY g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922655" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922655" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531613" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531613" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:51 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:50 +0200 Message-ID: <20230908104438.125454-30-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 11/17] lib/kunit: Fail / skip on kernel taint X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Similar to how igt_kselftest() handles kernel taints, fail current dynamic sub-subtest and skip remaining ones when a kernel taint is detected during execution of kunit test cases. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 020df286b8..988ac164cb 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -761,6 +761,7 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) bool is_builtin; struct ktap_test_results *results; struct ktap_test_results_element *temp; + unsigned long taints; int flags, ret; igt_skip_on_f(tst->kmsg < 0, "Could not open /dev/kmsg\n"); @@ -785,12 +786,20 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) while (READ_ONCE(results->still_running) || READ_ONCE(results->head) != NULL) { + if (igt_kernel_tainted(&taints)) { + ktap_parser_cancel(); + break; + } + if (READ_ONCE(results->head) != NULL) { pthread_mutex_lock(&results->mutex); - igt_dynamic(results->head->test_name) + igt_dynamic(results->head->test_name) { igt_assert(READ_ONCE(results->head->passed)); + igt_fail_on(igt_kernel_tainted(&taints)); + } + temp = results->head; results->head = results->head->next; free(temp); @@ -801,6 +810,7 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) ret = ktap_parser_stop(); + igt_skip_on(igt_kernel_tainted(&taints)); igt_skip_on_f(ret, "KTAP parser failed\n"); } From patchwork Fri Sep 8 10:44:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377353 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D15EDEE57F3 for ; Fri, 8 Sep 2023 10:47:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B9F1D10E8B0; Fri, 8 Sep 2023 10:46:58 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2553410E8A8; Fri, 8 Sep 2023 10:46:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170016; x=1725706016; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HhDqo32MszZssHLTSAT2xyQFfOK8Zqcmn9pBpLwuOmc=; b=lceYuIlc6siChVdOh4rz/ChA0GmAyPgqLDwq3hYKbO4ZtR2SxC4qjRaP B7MDzo+PJU6h1aHq4sCtwTlu+PnSkssFEpQPwFnA6ml5+X1zhhXTmFLVi p8B25jbf4gQdxMMxddMM0qUz5uG0XY8eDqD3QdwMeoepjhzK5B1Jb1wAR G1cnvUipWqIp+yVRCJwJ8Gqm6YiEWojkRu2wSIxoKAcorj6KM1ABfarfy cbP8OZcseTDWm0MLv1ewj5eVQ6PsTlZHjndSmc6uP9X6DVg3+hCYth/MZ mR92MLwcgVuFTc4xNWytMUHGmu5DsD+/YtnwAC5K6l0O2am5q0jttCumS w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922665" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922665" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531617" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531617" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:53 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:51 +0200 Message-ID: <20230908104438.125454-31-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 12/17] lib/ktap: Use IGT linked lists for storing KTAP results X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" For code simplicity and clarity, use existing IGT linked lists library instead of open coding a custom implementation of a list of KTAP results. While being at it, flatten the code by inverting a check for pending results. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 28 ++++++++++++++++------------ lib/igt_ktap.c | 25 +++++-------------------- lib/igt_ktap.h | 6 ++++-- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 988ac164cb..c692954911 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -760,7 +760,6 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) struct kmod_module *kunit_kmod; bool is_builtin; struct ktap_test_results *results; - struct ktap_test_results_element *temp; unsigned long taints; int flags, ret; @@ -784,28 +783,33 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) igt_skip("Unable to load %s module\n", tst->module_name); } - while (READ_ONCE(results->still_running) || READ_ONCE(results->head) != NULL) + while (READ_ONCE(results->still_running) || !igt_list_empty(&results->list)) { + struct ktap_test_results_element *result; + if (igt_kernel_tainted(&taints)) { ktap_parser_cancel(); break; } - if (READ_ONCE(results->head) != NULL) { - pthread_mutex_lock(&results->mutex); + pthread_mutex_lock(&results->mutex); + if (igt_list_empty(&results->list)) { + pthread_mutex_unlock(&results->mutex); + continue; + } - igt_dynamic(results->head->test_name) { - igt_assert(READ_ONCE(results->head->passed)); + result = igt_list_first_entry(&results->list, result, link); - igt_fail_on(igt_kernel_tainted(&taints)); - } + igt_list_del(&result->link); + pthread_mutex_unlock(&results->mutex); - temp = results->head; - results->head = results->head->next; - free(temp); + igt_dynamic(result->test_name) { + igt_assert(READ_ONCE(result->passed)); - pthread_mutex_unlock(&results->mutex); + igt_fail_on(igt_kernel_tainted(&taints)); } + + free(result); } ret = ktap_parser_stop(); diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 165f6b2cce..5e9967f980 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -12,6 +12,7 @@ #include "igt_aux.h" #include "igt_core.h" #include "igt_ktap.h" +#include "igt_list.h" #define DELIMITER "-" @@ -335,7 +336,7 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f bool *found_tests, bool is_builtin) { char record[BUF_LEN + 1]; - struct ktap_test_results_element *r, *temp; + struct ktap_test_results_element *r; int internal_test_count; char test_name[BUF_LEN + 1]; char base_test_name_for_next_level[BUF_LEN + 1]; @@ -403,17 +404,9 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f r->test_name[BUF_LEN] = '\0'; r->passed = false; - r->next = NULL; pthread_mutex_lock(&results.mutex); - if (results.head == NULL) { - results.head = r; - } else { - temp = results.head; - while (temp->next != NULL) - temp = temp->next; - temp->next = r; - } + igt_list_add_tail(&r->link, &results.list); pthread_mutex_unlock(&results.mutex); test_name[0] = '\0'; @@ -431,17 +424,9 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f r->test_name[BUF_LEN] = '\0'; r->passed = true; - r->next = NULL; pthread_mutex_lock(&results.mutex); - if (results.head == NULL) { - results.head = r; - } else { - temp = results.head; - while (temp->next != NULL) - temp = temp->next; - temp->next = r; - } + igt_list_add_tail(&r->link, &results.list); pthread_mutex_unlock(&results.mutex); test_name[0] = '\0'; @@ -523,7 +508,7 @@ static pthread_t ktap_parser_thread; struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) { - results.head = NULL; + IGT_INIT_LIST_HEAD(&results.list); pthread_mutex_init(&results.mutex, NULL); results.still_running = true; diff --git a/lib/igt_ktap.h b/lib/igt_ktap.h index 991800e912..b4d7a6dbc7 100644 --- a/lib/igt_ktap.h +++ b/lib/igt_ktap.h @@ -28,16 +28,18 @@ #include +#include "igt_list.h" + void *igt_ktap_parser(void *unused); typedef struct ktap_test_results_element { char test_name[BUF_LEN + 1]; bool passed; - struct ktap_test_results_element *next; + struct igt_list_head link; } ktap_test_results_element; struct ktap_test_results { - ktap_test_results_element *head; + struct igt_list_head list; pthread_mutex_t mutex; bool still_running; }; From patchwork Fri Sep 8 10:44:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377354 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F0E53EE57EF for ; Fri, 8 Sep 2023 10:47:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5964610E8B5; Fri, 8 Sep 2023 10:47:02 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id D0BBB10E8B1; Fri, 8 Sep 2023 10:46:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170018; x=1725706018; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7epak4WrIXwvNqqnPc50ybAlBHp5FxeBIVBAkdnwh74=; b=XMQEHl3lzInxrrvfOJj6z7v8fpVQvg3/zitSsiZC4xZWVaAwEdv5i1Gx EjPmB7PDLQwv3ZvIPoRPHEZrXVQQSWw67GXacLiQWx0qFlqxQjAxuJME0 Qr5YmZNs47oXKZxJQza08stc/VRB+KJsmiwmq26uRA1USQm9s951By5la SHXMCOF5RbT3Lm8cDdlqtXt0REL6U/5UGml9QAZrhbp0/FehXoWcJvCKv KCsBDJg0YESninFQJcxcsY5ykLe/IVq6PXf83JD/0jv9avPkiXe7wp8Ky PMD4CU4hWTRW7XUnw5jxUjn6KnlZUqsoc52Ygb5Igvdda5KoSU7d7dbDf g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922669" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922669" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531620" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531620" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:56 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:52 +0200 Message-ID: <20230908104438.125454-32-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 13/17] lib/ktap: Reimplement KTAP parser X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Current implementation of KTAP parser suffers from several issues: - in most cases, kernel messages that are not part of KTAP output but happen to appear in between break the parser, - results from parametrized test cases, not preceded with a "1..N" test plan, break the parser, - skips are not supported, reported as success, - IGT results from all 3 kunit test nesting levels, i.e., from parametrized subtests (should those were fixed to work correctly), test cases and test suites, are reported individually as if all those items were executed sequentially, all at the same level of nesting, which can be confusing to igt_runner, - the parser is not only parsing the data, but also handles data input from a /dev/kmsg like source, which is integrated into it, making it hard if not impossible to feed KTAP data from different sources, including mock sources, - since the parser has been designed for running it in a separate thread, it's not possible to use igt_skip() nor igt_fail() and friends immediately when a result is available, only pass it to the main thread over a buffer. As a consequence, it is virtually impossible to synchronize IGT output with KTAP output. Fixing the existing parser occurred more complicated than re-implementing it from scratch. This patch provides a new implementation. Only results from kunit test cases are reported as results of IGT dynamic sub-subtests. Results from individual parametrized subtests have been considered problematic since many of them provide multi-word descriptions in place of single-word subtest names. If a parametrized test case fails then full KTAP output from its subtests, potentially mixed with accompanying kernel messages, is available in dmesg for analysis so users can still find out which individual subtests succeeded and which failed. Results from test suites level are also omitted in faith that IGT can handle aggregation of results from individual kunit test cases reported as IGT dynamic sub-subtests and report those aggregated results correctly as results from an IGT dynamic subtest. That 1:1 mapping of kunit test suites to IGT dynamic subtests now works perfectly for modules that provide only one test suite, which is the case for all kunit test modules now existing under drivers/gpu/drm, and the most common case among all kunit test modules in the whole kernel tree. New igt_ktap functions can be called directly from igt_kunit subtest body, but for this patch, the old igt_ktap_parser() function that runs in a separate thread has been preserved, only modified to use the new implementation and translate results from those new functions to legacy format. Unlike the former implementation, translation of kunit names to IGT names is handled outside the parser itself, though for now it is still performed inside the legacy igt_ktap_parser() function. For better readability of the patch, no longer used functions have been left untouched, only tagged with __maybe_unused to shut up compiler warnings / errors. Kunit library functions will be modified to use the new igt_ktap interface, and those old ktap functions removed by follow- up patches. A test with example subtests that feed igt_ktap_parse() function with some example data and verifies correctness of their parsing is also provided. Signed-off-by: Janusz Krzysztofik --- lib/igt_ktap.c | 422 ++++++++++++++++++++++++++++++++---- lib/igt_ktap.h | 15 ++ lib/tests/igt_ktap_parser.c | 235 ++++++++++++++++++++ lib/tests/meson.build | 1 + 4 files changed, 634 insertions(+), 39 deletions(-) create mode 100644 lib/tests/igt_ktap_parser.c diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 5e9967f980..d46a2433e5 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT /* * Copyright © 2023 Isabella Basso do Amaral + * Copyright © 2023 Intel Corporation */ #include @@ -8,12 +9,310 @@ #include #include #include +#include +#include +#include +#include #include "igt_aux.h" #include "igt_core.h" #include "igt_ktap.h" #include "igt_list.h" +enum ktap_phase { + KTAP_START, + SUITE_COUNT, + SUITE_START, + SUITE_NAME, + CASE_COUNT, + CASE_NAME, + SUB_RESULT, + CASE_RESULT, + SUITE_RESULT, +}; + +struct igt_ktap_results { + enum ktap_phase expect; + unsigned int suite_count; + unsigned int suite_last; + char *suite_name; + unsigned int case_count; + unsigned int case_last; + char *case_name; + unsigned int sub_last; + struct igt_list_head *results; +}; + +/** + * igt_ktap_parse: + * + * This function parses a line of text for KTAP report data + * and passes results back to IGT kunit layer. + */ +int igt_ktap_parse(const char *buf, struct igt_ktap_results *ktap) +{ + char *suite_name = NULL, *case_name = NULL, *msg = NULL; + struct igt_ktap_result *result; + int code = IGT_EXIT_INVALID; + unsigned int n, len; + char s[2]; + + /* KTAP report header */ + if (igt_debug_on(sscanf(buf, "KTAP%*[ ]version%*[ ]%u %n", + &n, &len) == 1 && len == strlen(buf))) { + if (igt_debug_on(ktap->expect != KTAP_START)) + return -EPROTO; + + ktap->suite_count = 0; + ktap->expect = SUITE_COUNT; + + /* malformed TAP test plan? */ + } else if (len = 0, + igt_debug_on(sscanf(buf, " 1..%1[ ]", s) == 1)) { + return -EINPROGRESS; + + /* valid test plan of a KTAP report */ + } else if (igt_debug_on(sscanf(buf, "1..%u %n", &n, &len) == 1 && + len == strlen(buf))) { + if (igt_debug_on(ktap->expect != SUITE_COUNT)) + return -EPROTO; + + if (!n) + return 0; + + ktap->suite_count = n; + ktap->suite_last = 0; + ktap->suite_name = NULL; + ktap->expect = SUITE_START; + + /* KTAP test suite header */ + } else if (len = 0, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]KTAP%*[ ]version%*[ ]%u %n", + &n, &len) == 1 && len == strlen(buf))) { + /* + * TODO: drop the following workaround as soon as + * kernel side issue of missing lines with top level + * KTAP version and test suite plan is fixed. + */ + if (ktap->expect == KTAP_START) { + ktap->suite_count = 1; + ktap->suite_last = 0; + ktap->suite_name = NULL; + ktap->expect = SUITE_START; + } + + if (igt_debug_on(ktap->expect != SUITE_START)) + return -EPROTO; + + ktap->expect = SUITE_NAME; + + /* KTAP test suite name */ + } else if (len = 0, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]#%*[ ]Subtest:%*[ ]%ms %n", + &suite_name, &len) == 1 && len == strlen(buf))) { + if (igt_debug_on(ktap->expect != SUITE_NAME)) + return -EPROTO; + + ktap->suite_name = suite_name; + suite_name = NULL; + ktap->case_count = 0; + ktap->expect = CASE_COUNT; + + /* valid test plan of a KTAP test suite */ + } else if (len = 0, free(suite_name), suite_name = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]1..%u %n", + &n, &len) == 1 && len == strlen(buf))) { + if (igt_debug_on(ktap->expect != CASE_COUNT)) + return -EPROTO; + + if (n) { + ktap->case_count = n; + ktap->case_last = 0; + ktap->case_name = NULL; + ktap->expect = CASE_RESULT; + } else { + ktap->expect = SUITE_RESULT; + } + + /* KTAP parametrized test case header */ + } else if (len = 0, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]KTAP%*[ ]version%*[ ]%u %n", + &n, &len) == 1 && len == strlen(buf))) { + if (igt_debug_on(ktap->expect != CASE_RESULT)) + return -EPROTO; + + ktap->sub_last = 0; + ktap->expect = CASE_NAME; + + /* KTAP parametrized test case name */ + } else if (len = 0, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]#%*[ ]Subtest:%*[ ]%ms %n", + &case_name, &len) == 1 && len == strlen(buf))) { + if (igt_debug_on(ktap->expect != CASE_NAME)) + return -EPROTO; + + n = ktap->case_last + 1; + ktap->expect = SUB_RESULT; + + /* KTAP parametrized subtest result */ + } else if (len = 0, free(case_name), case_name = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]ok%*[ ]%u%*[ ]%*[^#\n]%1[#\n]", + &n, s) == 2) || + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]%*1[ ]not%*1[ ]ok%*[ ]%u%*[ ]%*[^#\n]%1[#\n]", + &n, s) == 2)) { + /* at lease one result of a parametrised subtest expected */ + if (igt_debug_on(ktap->expect == SUB_RESULT && + ktap->sub_last == 0)) + ktap->expect = CASE_RESULT; + + if (igt_debug_on(ktap->expect != CASE_RESULT) || + igt_debug_on(n != ++ktap->sub_last)) + return -EPROTO; + + /* KTAP test case skip result */ + } else if ((igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]ok%*[ ]%u%*[ ]%ms%*[ ]#%*[ ]SKIP %n", + &n, &case_name, &len) == 2 && + len == strlen(buf))) || + (len = 0, free(case_name), case_name = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]ok%*[ ]%u%*[ ]%ms%*[ ]#%*[ ]SKIP%*[ ]%m[^\n]", + &n, &case_name, &msg) == 3))) { + code = IGT_EXIT_SKIP; + + /* KTAP test case pass result */ + } else if ((free(case_name), case_name = NULL, free(msg), msg = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]ok%*[ ]%u%*[ ]%ms %n", + &n, &case_name, &len) == 2 && + len == strlen(buf))) || + (len = 0, free(case_name), case_name = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]ok%*[ ]%u%*[ ]%ms%*[ ]#%*[ ]%m[^\n]", + &n, &case_name, &msg) == 3))) { + code = IGT_EXIT_SUCCESS; + + /* KTAP test case fail result */ + } else if ((free(case_name), case_name = NULL, free(msg), msg = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]not%*1[ ]ok%*[ ]%u%*[ ]%ms %n", + &n, &case_name, &len) == 2 && + len == strlen(buf))) || + (len = 0, free(case_name), case_name = NULL, + igt_debug_on(sscanf(buf, + "%*1[ ]%*1[ ]%*1[ ]%*1[ ]not%*1[ ]ok%*[ ]%u%*[ ]%ms%*[ ]#%*[ ]%m[^\n]", + &n, &case_name, &msg) == 3))) { + code = IGT_EXIT_FAILURE; + + /* KTAP test suite result */ + } else if ((free(case_name), free(msg), + igt_debug_on(sscanf(buf, "ok%*[ ]%u%*[ ]%ms %n", + &n, &suite_name, &len) == 2 && + len == strlen(buf))) || + (len = 0, free(suite_name), suite_name = NULL, + igt_debug_on(sscanf(buf, "ok%*[ ]%u%*[ ]%ms%*[ ]%1[#]", + &n, &suite_name, s) == 3)) || + (free(suite_name), suite_name = NULL, + igt_debug_on(sscanf(buf, + "not%*[ ]ok%*[ ]%u%*[ ]%ms %n", + &n, &suite_name, &len) == 2 && + len == strlen(buf))) || + (len = 0, free(suite_name), suite_name = NULL, + igt_debug_on(sscanf(buf, + "not%*[ ]ok%*[ ]%u%*[ ]%ms%*[ ]%1[#]", + &n, &suite_name, s) == 3))) { + if (igt_debug_on(ktap->expect != SUITE_RESULT) || + igt_debug_on(strcmp(suite_name, ktap->suite_name)) || + igt_debug_on(n != ++ktap->suite_last) || + igt_debug_on(n > ktap->suite_count)) { + free(suite_name); + return -EPROTO; + } + free(suite_name); + + /* last test suite? */ + if (igt_debug_on(n == ktap->suite_count)) + return 0; + + ktap->suite_name = NULL; + ktap->expect = SUITE_START; + + } else { + return -EINPROGRESS; + } + + /* neither a test case name nor result */ + if (ktap->expect != SUB_RESULT && code == IGT_EXIT_INVALID) + return -EINPROGRESS; + + if (igt_debug_on(ktap->expect == SUB_RESULT && + code != IGT_EXIT_INVALID) || + igt_debug_on(code != IGT_EXIT_INVALID && + ktap->expect != CASE_RESULT) || + igt_debug_on(!ktap->suite_name) || igt_debug_on(!case_name) || + igt_debug_on(ktap->expect == CASE_RESULT && ktap->case_name && + strcmp(case_name, ktap->case_name)) || + igt_debug_on(n > ktap->case_count) || + igt_debug_on(n != (ktap->expect == SUB_RESULT ? + ktap->case_last + 1: ++ktap->case_last))) { + free(case_name); + free(msg); + return -EPROTO; + } + + if (ktap->expect == SUB_RESULT) { + /* KTAP parametrized test case name */ + ktap->case_name = case_name; + + } else { + /* KTAP test case result */ + ktap->case_name = NULL; + + /* last test case in a suite */ + if (n == ktap->case_count) + ktap->expect = SUITE_RESULT; + } + + if (igt_debug_on((result = calloc(1, sizeof(*result)), !result))) { + free(case_name); + free(msg); + return -ENOMEM; + } + + result->suite_name = ktap->suite_name; + result->case_name = case_name; + result->code = code; + result->msg = msg; + igt_list_add_tail(&result->link, ktap->results); + + return -EINPROGRESS; +} + +struct igt_ktap_results *igt_ktap_alloc(struct igt_list_head *results) +{ + struct igt_ktap_results *ktap = calloc(1, sizeof(*ktap)); + + if (!ktap) + return NULL; + + ktap->expect = KTAP_START; + ktap->results = results; + + return ktap; +} + +void igt_ktap_free(struct igt_ktap_results *ktap) +{ + free(ktap); +} + #define DELIMITER "-" struct ktap_parser_args { @@ -332,6 +631,7 @@ static int parse_kmsg_for_tap(int fd, char *record, char *test_name) * 0 if succeded * -1 if error occurred */ +__maybe_unused static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *failed_tests, bool *found_tests, bool is_builtin) { @@ -445,62 +745,106 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f */ void *igt_ktap_parser(void *unused) { + char record[BUF_LEN + 1], *buf, *suite_name = NULL, *case_name = NULL; + struct igt_ktap_results *ktap = NULL; int fd = ktap_args.fd; - char record[BUF_LEN + 1]; - bool is_builtin = ktap_args.is_builtin; - char test_name[BUF_LEN + 1]; - bool failed_tests, found_tests; - int test_count; + IGT_LIST_HEAD(list); + int err; - failed_tests = false; - found_tests = false; + ktap = igt_ktap_alloc(&list); + if (igt_debug_on(!ktap)) + goto igt_ktap_parser_end; -igt_ktap_parser_start: - test_name[0] = '\0'; - test_name[BUF_LEN] = '\0'; + while (err = read(fd, record, BUF_LEN), err > 0) { + struct igt_ktap_result *r, *rn; - if (read(fd, record, BUF_LEN) < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("error reading kmsg (%m)\n"); + /* skip kmsg continuation lines */ + if (igt_debug_on(*record == ' ')) + continue; - goto igt_ktap_parser_end; - } + /* NULL-terminate the record */ + record[err] = '\0'; - test_count = find_next_tap_subtest(fd, record, test_name, is_builtin); + /* detect start of log message, continue if not found */ + buf = strchrnul(record, ';'); + if (igt_debug_on(*buf == '\0')) + continue; + buf++; - switch (test_count) { - case -2: - /* Problems while reading the file */ - goto igt_ktap_parser_end; - case -1: - /* No test found */ - goto igt_ktap_parser_start; - case 0: - /* Tests found, but they're missing info */ - found_tests = true; - goto igt_ktap_parser_end; - default: - found_tests = true; + err = igt_ktap_parse(buf, ktap); - if (parse_tap_level(fd, test_name, test_count, &failed_tests, &found_tests, - is_builtin) == -1) + /* parsing error */ + if (err && err != -EINPROGRESS) goto igt_ktap_parser_end; - break; + igt_list_for_each_entry_safe(r, rn, &list, link) { + struct ktap_test_results_element *result = NULL; + int code = r->code; + + if (code != IGT_EXIT_INVALID) + result = calloc(1, sizeof(*result)); + + if (result) { + snprintf(result->test_name, sizeof(result->test_name), + "%s-%s", r->suite_name, r->case_name); + + if (code == IGT_EXIT_SUCCESS) + result->passed = true; + } + + igt_list_del(&r->link); + if (r->suite_name != suite_name) { + free(suite_name); + suite_name = r->suite_name; + } + if (r->case_name != case_name) { + free(case_name); + case_name = r->case_name; + } + free(r->msg); + free(r); + + /* + * no extra result record expected on start + * of parametrized test case -- skip it + */ + if (code == IGT_EXIT_INVALID) + continue; + + if (!result) { + err = -ENOMEM; + goto igt_ktap_parser_end; + } + + pthread_mutex_lock(&results.mutex); + igt_list_add_tail(&result->link, &results.list); + pthread_mutex_unlock(&results.mutex); + } + + /* end of KTAP report */ + if (!err) + goto igt_ktap_parser_end; } - /* Parse topmost level */ - test_name[0] = '\0'; - parse_tap_level(fd, test_name, test_count, &failed_tests, &found_tests, is_builtin); + if (err < 0) { + if (errno == EPIPE) + igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); + else if (errno != EINTR) + igt_warn("error reading kmsg (%m)\n"); + } igt_ktap_parser_end: - results.still_running = false; + free(suite_name); + free(case_name); - if (found_tests && !failed_tests) + if (!err) ktap_args.ret = IGT_EXIT_SUCCESS; + results.still_running = false; + + if (ktap) + igt_ktap_free(ktap); + return NULL; } diff --git a/lib/igt_ktap.h b/lib/igt_ktap.h index b4d7a6dbc7..6f8da3eab6 100644 --- a/lib/igt_ktap.h +++ b/lib/igt_ktap.h @@ -1,5 +1,6 @@ /* * Copyright © 2022 Isabella Basso do Amaral + * Copyright © 2023 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,6 +31,20 @@ #include "igt_list.h" +struct igt_ktap_result { + struct igt_list_head link; + char *suite_name; + char *case_name; + char *msg; + int code; +}; + +struct igt_ktap_results; + +struct igt_ktap_results *igt_ktap_alloc(struct igt_list_head *results); +int igt_ktap_parse(const char *buf, struct igt_ktap_results *ktap); +void igt_ktap_free(struct igt_ktap_results *ktap); + void *igt_ktap_parser(void *unused); typedef struct ktap_test_results_element { diff --git a/lib/tests/igt_ktap_parser.c b/lib/tests/igt_ktap_parser.c new file mode 100644 index 0000000000..45a700b4c4 --- /dev/null +++ b/lib/tests/igt_ktap_parser.c @@ -0,0 +1,235 @@ +#include "../igt_core.c" +#include "../igt_ktap.h" + +static void ktap_list(void) +{ + struct igt_ktap_result *result, *rn; + struct igt_ktap_results *ktap; + int suite = 1, test = 1; + IGT_LIST_HEAD(results); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + + igt_assert_eq(igt_ktap_parse("KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("1..3\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite_1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" 1..3\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 1 test_case_1 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 2 test_case_2 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 3 test_case_3 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("ok 1 test_suite_1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite_2\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" 1..1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 1 test_case_1 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("ok 2 test_suite_2\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite_3\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" 1..4\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 1 test_case_1 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 2 test_case_2 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 3 test_case_3 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 4 test_case_4 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("ok 3 test_suite_3\n", ktap), 0); + + igt_ktap_free(ktap); + + igt_assert_eq(igt_list_length(&results), 8); + + igt_list_for_each_entry_safe(result, rn, &results, link) { + char *case_name, *suite_name; + + igt_list_del(&result->link); + + igt_assert_lt(0, asprintf(&case_name, "test_case_%u", test)); + igt_assert_lt(0, asprintf(&suite_name, "test_suite_%u", suite)); + + igt_assert(result->case_name); + igt_assert_eq(strcmp(result->case_name, case_name), 0); + free(result->case_name); + free(case_name); + + igt_assert(result->suite_name); + igt_assert_eq(strcmp(result->suite_name, suite_name), 0); + free(suite_name); + + igt_assert(!result->msg); + igt_assert_eq(result->code, IGT_EXIT_SKIP); + + if ((suite == 1 && test < 3) || (suite == 3 && test < 4)) { + test++; + } else { + free(result->suite_name); + suite++; + test = 1; + } + + free(result); + } +} + +static void ktap_results(void) +{ + struct igt_ktap_result *result; + struct igt_ktap_results *ktap; + char *suite_name, *case_name; + IGT_LIST_HEAD(results); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + + igt_assert_eq(igt_ktap_parse("KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("1..1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" 1..1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_case\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 1 parameter 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 2 parameter 2 # a comment\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 3 parameter 3 # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 4 parameter 4 # SKIP with a message\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" not ok 5 parameter 5\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" not ok 6 parameter 6 # failure message\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" ok 1 test_case\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("not ok 1 test_suite\n", ktap), 0); + + igt_ktap_free(ktap); + + igt_assert_eq(igt_list_length(&results), 2); + + result = igt_list_first_entry(&results, result, link); + igt_list_del(&result->link); + igt_assert_eq(strcmp(result->suite_name, "test_suite"), 0); + igt_assert_eq(strcmp(result->case_name, "test_case"), 0); + igt_assert_eq(result->code, IGT_EXIT_INVALID); + igt_assert(!result->msg); + free(result->msg); + suite_name = result->suite_name; + case_name = result->case_name; + free(result); + + result = igt_list_first_entry(&results, result, link); + igt_list_del(&result->link); + igt_assert_eq(strcmp(result->suite_name, suite_name), 0); + igt_assert_eq(strcmp(result->case_name, case_name), 0); + igt_assert_neq(result->code, IGT_EXIT_INVALID); + free(result->msg); + free(suite_name); + free(case_name); + free(result); +} + +static void ktap_success(void) +{ + struct igt_ktap_result *result; + struct igt_ktap_results *ktap; + IGT_LIST_HEAD(results); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + + igt_assert_eq(igt_ktap_parse("KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse("1..1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" 1..1\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_assert(igt_list_empty(&results)); + + igt_assert_eq(igt_ktap_parse(" # Subtest: test_case\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_list_length(&results), 1); + + igt_assert_eq(igt_ktap_parse(" ok 1 parameter # SKIP\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_list_length(&results), 1); + + igt_assert_eq(igt_ktap_parse(" ok 1 test_case\n", ktap), -EINPROGRESS); + igt_assert_eq(igt_list_length(&results), 2); + + igt_assert_eq(igt_ktap_parse("not ok 1 test_suite\n", ktap), 0); + igt_assert_eq(igt_list_length(&results), 2); + + igt_ktap_free(ktap); + + result = igt_list_last_entry(&results, result, link); + igt_list_del(&result->link); + igt_assert_eq(result->code, IGT_EXIT_SUCCESS); + free(result->msg); + free(result); + + result = igt_list_last_entry(&results, result, link); + igt_list_del(&result->link); + free(result->suite_name); + free(result->case_name); + free(result->msg); + free(result); +} + +static void ktap_top_version(void) +{ + struct igt_ktap_results *ktap; + IGT_LIST_HEAD(results); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse("1..1\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + /* TODO: change to -EPROTO as soon as related workaround is dropped */ + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EINPROGRESS); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_suite\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" 1..1\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" KTAP version 1\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" # Subtest: test_case\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" ok 1 parameter 1\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse(" ok 1 test_case\n", ktap), -EPROTO); + igt_ktap_free(ktap); + + ktap = igt_ktap_alloc(&results); + igt_require(ktap); + igt_assert_eq(igt_ktap_parse("ok 1 test_suite\n", ktap), -EPROTO); + igt_ktap_free(ktap); +} + +igt_main +{ + igt_subtest("list") + ktap_list(); + + igt_subtest("results") + ktap_results(); + + igt_subtest("success") + ktap_success(); + + igt_subtest("top-ktap-version") + ktap_top_version(); +} diff --git a/lib/tests/meson.build b/lib/tests/meson.build index 7a52a7876e..fa3d81de6c 100644 --- a/lib/tests/meson.build +++ b/lib/tests/meson.build @@ -10,6 +10,7 @@ lib_tests = [ 'igt_exit_handler', 'igt_fork', 'igt_fork_helper', + 'igt_ktap_parser', 'igt_list_only', 'igt_invalid_subtest_name', 'igt_nesting', From patchwork Fri Sep 8 10:44:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377357 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5EA2EEE57EB for ; Fri, 8 Sep 2023 10:47:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9F4F810E8AA; Fri, 8 Sep 2023 10:47:08 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id EDB9F10E8B5; Fri, 8 Sep 2023 10:47:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170021; x=1725706021; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=f8NLoL4jonuu5A4stu9eDR2bvxQQ/BqeXe9fJeYugv0=; b=gg/CW2EIH1YE++hwD0Gk1F35+MZ5aOobsI3F3TnV/X0LySOdlkjGPHF2 BdGWJa97iQ5ZaZmwmLLJ/YdggV3L9MErT2/IHPrZtQGkdhsEB8lhvCTIW vXuvYNKpRHzPq02vBQquXM5OjUJ8WV1j4a7zD4IyahqcKKYZG1aVQ/7WF A8F11cnbIY95sH13I0Wv2QTBA0vQckS6RlPN/X942FKB2BPEyVh+qWsJi /OtGpoLYUHWcwdAG8g9xNU+pjjTPgp3sErpOK4bUWlcySnSaVRfGdyDoY a++k464UuChhWYKGkekUp6tfI2A04m9MmyncGcWusm6TccXQigIgZqCIL A==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922675" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922675" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531625" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531625" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:46:58 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:53 +0200 Message-ID: <20230908104438.125454-33-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 14/17] lib/kunit: Load test modules in background X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" For igt_runner to be able to correlate a stream of IGT results from dynamic sub-subtests that correspond to individual kunit test cases, read by the igt_runner from stdout / stderr of the test process, with a stream of kernel messages read from /dev/kmsg, we need both result streams being fed with data in parallel. While our KTAP parser is currently started in the background and reads KTAP results from /dev/kmsg in parallel with execution of kunit tests performed by the kernel while we are loading a kunit test module, results from the parser are then only stored as intermediate data and not processed any further until the module loading completes. As a consequence, there is no synchronization between the two streams. Call the function that loads the kunit test module from a separate thread and process the intermediate results immediately, as soon as available from the background parser, without waiting for completion of module loading. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index c692954911..bbde3929f2 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "igt_aux.h" @@ -746,6 +747,21 @@ void igt_kselftest_get_tests(struct kmod_module *kmod, kmod_module_info_free_list(pre); } +struct modprobe_data { + struct kmod_module *kmod; + const char *opts; + int err; +}; + +static void *modprobe_task(void *arg) +{ + struct modprobe_data *data = arg; + + data->err = modprobe(data->kmod, data->opts); + + return NULL; +} + /** * igt_kunit: * @module_name: the name of the module @@ -757,9 +773,11 @@ void igt_kselftest_get_tests(struct kmod_module *kmod, */ static void __igt_kunit(struct igt_ktest *tst, const char *opts) { + struct modprobe_data modprobe = { tst->kmod, opts, 0, }; struct kmod_module *kunit_kmod; bool is_builtin; struct ktap_test_results *results; + pthread_t modprobe_thread; unsigned long taints; int flags, ret; @@ -777,18 +795,25 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) results = ktap_parser_start(tst->kmsg, is_builtin); - if (igt_debug_on(igt_kmod_load(tst->module_name, opts) < 0)) { + if (igt_debug_on(pthread_create(&modprobe_thread, NULL, + modprobe_task, &modprobe))) { ktap_parser_cancel(); igt_ignore_warn(ktap_parser_stop()); - igt_skip("Unable to load %s module\n", tst->module_name); + igt_skip("Failed to create a modprobe thread\n"); } while (READ_ONCE(results->still_running) || !igt_list_empty(&results->list)) { struct ktap_test_results_element *result; + if (!pthread_tryjoin_np(modprobe_thread, NULL) && modprobe.err) { + ktap_parser_cancel(); + break; + } + if (igt_kernel_tainted(&taints)) { ktap_parser_cancel(); + pthread_cancel(modprobe_thread); break; } @@ -806,14 +831,20 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) igt_dynamic(result->test_name) { igt_assert(READ_ONCE(result->passed)); + if (!pthread_tryjoin_np(modprobe_thread, NULL)) + igt_assert_eq(modprobe.err, 0); + igt_fail_on(igt_kernel_tainted(&taints)); } free(result); } + pthread_join(modprobe_thread, NULL); + ret = ktap_parser_stop(); + igt_skip_on(modprobe.err); igt_skip_on(igt_kernel_tainted(&taints)); igt_skip_on_f(ret, "KTAP parser failed\n"); } From patchwork Fri Sep 8 10:44:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377356 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E4B6CEE57EF for ; Fri, 8 Sep 2023 10:47:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3A40F10E8A9; Fri, 8 Sep 2023 10:47:07 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 79A4A10E8B8; Fri, 8 Sep 2023 10:47:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170023; x=1725706023; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wvy+dohSHRYejjScNuh+WvByGeX2iqjgKK3hglJ6QrI=; b=j3vkYu485Qs/yd9j13to6Ow0BS9nbugDQAWEH3B+25hst67WBRZ/M0g2 2ONCjmsdBP1KGnwmW1EL5p8vNTyp0NA4jccUxe6/eOYu9p7MxIyTBgiVt 6tAmLOE8SWIzsg9XcI4w+ZBNzdFE7RMNIjUzET0cS+RcYA8f5MCbqhKoF rxjGANdqRBB1AO4bMEPOiuTj4NHZNrzNX5vsU9voOH1VU7ND5lLdhqdgR 642aiPN3uCsktwP8KmRBerOtmtUkF/Sgrp3HoY/zYH4turzOwUYiR25nG L2/zgb02KI3IvuyUG4paeMbLn/VwSDFlRPgbl7g47fJwKe2uBt/2zIw0R w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922681" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922681" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531638" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531638" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:00 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:54 +0200 Message-ID: <20230908104438.125454-34-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 15/17] lib/kunit: Parse KTAP report from the main process thread X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" There was an attempt to parse KTAP reports in the background while a kunit test module is loading. However, since dynamic sub-subtests can be executed only from the main thread, that attempt was not quite successful, as IGT results from all executed kunit test cases were generated only after loading of kunit test module completed. Now that the parser maintains its state and we can call it separately for each input line of a KTAP report, it is perfectly possible to call the parser from the main thread while the module is loading in the background, and convert results from kunit test cases immediately to results of IGT dynamic sub-subtests by running an igt_dynamic() section for each result as soon as returned by the parser. Drop igt_ktap_parser() thread and execute igt_dynamic() for each kunit result obtained from igt_ktap_parse() called from the main thread. Also, drop no longer needed functions from igt_ktap soruces. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 158 +++++++++++--- lib/igt_ktap.c | 568 ------------------------------------------------- lib/igt_ktap.h | 22 -- 3 files changed, 123 insertions(+), 625 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index bbde3929f2..46a6f81e73 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -1,5 +1,5 @@ /* - * Copyright © 2016 Intel Corporation + * Copyright © 2016-2023 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,7 +26,10 @@ #include #include #include +#include +#include #include +#include #include "igt_aux.h" #include "igt_core.h" @@ -762,6 +765,54 @@ static void *modprobe_task(void *arg) return NULL; } +static int kunit_kmsg_result_get(struct igt_list_head *results, + int fd, struct igt_ktap_results *ktap) +{ + char record[BUF_LEN + 1], *buf; + int ret; + + while (igt_list_empty(results) && + (ret = read(fd, record, BUF_LEN), ret > 0)) { + /* skip kmsg continuation lines */ + if (igt_debug_on(*record == ' ')) + continue; + + /* NULL-terminate the record */ + record[ret] = '\0'; + + /* detect start of log message, continue if not found */ + buf = strchrnul(record, ';'); + if (igt_debug_on(*buf == '\0')) + continue; + buf++; + + ret = igt_ktap_parse(buf, ktap); + if (ret != -EINPROGRESS) + break; + } + + return ret; +} + +static void kunit_result_free(struct igt_ktap_result *r, + char **suite_name, char **case_name) +{ + igt_list_del(&r->link); + + if (r->suite_name != *suite_name) { + free(*suite_name); + *suite_name = r->suite_name; + } + + if (r->case_name != *case_name) { + free(*case_name); + *case_name = r->case_name; + } + + free(r->msg); + free(r); +} + /** * igt_kunit: * @module_name: the name of the module @@ -774,10 +825,11 @@ static void *modprobe_task(void *arg) static void __igt_kunit(struct igt_ktest *tst, const char *opts) { struct modprobe_data modprobe = { tst->kmod, opts, 0, }; - struct kmod_module *kunit_kmod; - bool is_builtin; - struct ktap_test_results *results; + char *suite_name = NULL, *case_name = NULL; + struct igt_ktap_result *r, *rn; + struct igt_ktap_results *ktap; pthread_t modprobe_thread; + IGT_LIST_HEAD(results); unsigned long taints; int flags, ret; @@ -787,49 +839,76 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) igt_skip_on_f(fcntl(tst->kmsg, F_SETFL, flags) == -1, "Could not set /dev/kmsg to blocking mode\n"); - igt_skip_on(lseek(tst->kmsg, 0, SEEK_END) < 0); - - igt_skip_on(kmod_module_new_from_name(kmod_ctx(), "kunit", &kunit_kmod)); - is_builtin = kmod_module_get_initstate(kunit_kmod) == KMOD_MODULE_BUILTIN; - kmod_module_unref(kunit_kmod); + ktap = igt_ktap_alloc(&results); + igt_require(ktap); - results = ktap_parser_start(tst->kmsg, is_builtin); + igt_skip_on(lseek(tst->kmsg, 0, SEEK_END) < 0); if (igt_debug_on(pthread_create(&modprobe_thread, NULL, modprobe_task, &modprobe))) { - ktap_parser_cancel(); - igt_ignore_warn(ktap_parser_stop()); + igt_ktap_free(ktap); igt_skip("Failed to create a modprobe thread\n"); } - while (READ_ONCE(results->still_running) || !igt_list_empty(&results->list)) - { - struct ktap_test_results_element *result; + do { + if (!pthread_tryjoin_np(modprobe_thread, NULL) && modprobe.err) + break; - if (!pthread_tryjoin_np(modprobe_thread, NULL) && modprobe.err) { - ktap_parser_cancel(); + if (igt_kernel_tainted(&taints)) break; - } - if (igt_kernel_tainted(&taints)) { - ktap_parser_cancel(); - pthread_cancel(modprobe_thread); + ret = kunit_kmsg_result_get(&results, tst->kmsg, ktap); + if (igt_debug_on(ret && ret != -EINPROGRESS)) break; - } - pthread_mutex_lock(&results->mutex); - if (igt_list_empty(&results->list)) { - pthread_mutex_unlock(&results->mutex); - continue; - } + if (igt_debug_on(igt_list_empty(&results))) + break; + + r = igt_list_first_entry(&results, r, link); + + igt_dynamic_f("%s-%s", r->suite_name, r->case_name) { + if (r->code == IGT_EXIT_INVALID) { + /* parametrized test case, get actual result */ + kunit_result_free(r, &suite_name, &case_name); + r = NULL; - result = igt_list_first_entry(&results->list, result, link); + igt_assert(igt_list_empty(&results)); - igt_list_del(&result->link); - pthread_mutex_unlock(&results->mutex); + ret = kunit_kmsg_result_get(&results, + tst->kmsg, ktap); + if (ret != -EINPROGRESS) + igt_fail_on(ret); - igt_dynamic(result->test_name) { - igt_assert(READ_ONCE(result->passed)); + igt_fail_on(igt_list_empty(&results)); + + r = igt_list_first_entry(&results, r, link); + + igt_fail_on_f(strcmp(r->suite_name, suite_name), + "suite_name expected: %s, got: %s\n", + suite_name, r->suite_name); + igt_fail_on_f(strcmp(r->case_name, case_name), + "case_name expected: %s, got: %s\n", + case_name, r->case_name); + } + + igt_assert_neq(r->code, IGT_EXIT_INVALID); + + if (r->msg && *r->msg) { + igt_skip_on_f(r->code == IGT_EXIT_SKIP, + "%s", r->msg); + igt_fail_on_f(r->code == IGT_EXIT_FAILURE, + "%s", r->msg); + igt_abort_on_f(r->code == IGT_EXIT_ABORT, + "%s", r->msg); + } else { + igt_skip_on(r->code == IGT_EXIT_SKIP); + igt_fail_on(r->code == IGT_EXIT_FAILURE); + if (igt_debug_on(r->code != IGT_EXIT_SUCCESS)) + igt_fail(r->code); + } + + if (ret != -EINPROGRESS) + igt_assert_eq(ret, 0); if (!pthread_tryjoin_np(modprobe_thread, NULL)) igt_assert_eq(modprobe.err, 0); @@ -837,12 +916,21 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) igt_fail_on(igt_kernel_tainted(&taints)); } - free(result); - } + kunit_result_free(r, &suite_name, &case_name); + + } while (ret == -EINPROGRESS); + + igt_list_for_each_entry_safe(r, rn, &results, link) + kunit_result_free(r, &suite_name, &case_name); + free(case_name); + free(suite_name); + + if (ret) + pthread_cancel(modprobe_thread); pthread_join(modprobe_thread, NULL); - ret = ktap_parser_stop(); + igt_ktap_free(ktap); igt_skip_on(modprobe.err); igt_skip_on(igt_kernel_tainted(&taints)); diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index d46a2433e5..53a6c63288 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -4,17 +4,11 @@ * Copyright © 2023 Intel Corporation */ -#include -#include -#include -#include #include #include #include #include -#include -#include "igt_aux.h" #include "igt_core.h" #include "igt_ktap.h" #include "igt_list.h" @@ -312,565 +306,3 @@ void igt_ktap_free(struct igt_ktap_results *ktap) { free(ktap); } - -#define DELIMITER "-" - -struct ktap_parser_args { - int fd; - bool is_builtin; - int ret; -} ktap_args; - -static struct ktap_test_results results; - -static int log_to_end(enum igt_log_level level, int fd, - char *record, const char *format, ...) __attribute__((format(printf, 4, 5))); - -/** - * log_to_end: - * @level: #igt_log_level - * @record: record to store the read data - * @format: format string - * @...: optional arguments used in the format string - * - * This is an altered version of the generic structured logging helper function - * igt_log capable of reading to the end of a given line. - * - * Returns: 0 for success, or -2 if there's an error reading from the file - */ -static int log_to_end(enum igt_log_level level, int fd, - char *record, const char *format, ...) -{ - va_list args; - const char *lend; - - /* Cutoff after newline character, in order to not display garbage */ - char *cutoff = strchr(record, '\n'); - if (cutoff) { - if (cutoff - record < BUF_LEN) - cutoff[1] = '\0'; - } - - va_start(args, format); - igt_vlog(IGT_LOG_DOMAIN, level, format, args); - va_end(args); - - lend = strchrnul(record, '\n'); - while (*lend == '\0') { - igt_log(IGT_LOG_DOMAIN, level, "%s", record); - - if (read(fd, record, BUF_LEN) < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("an error occurred while reading kmsg: %m\n"); - - return -2; - } - - lend = strchrnul(record, '\n'); - } - return 0; -} - -/** - * lookup_value: - * @haystack: the string to search in - * @needle: the string to search for - * - * Returns: the value of the needle in the haystack, or -1 if not found. - */ -static long lookup_value(const char *haystack, const char *needle) -{ - const char *needle_rptr; - char *needle_end; - long num; - - needle_rptr = strcasestr(haystack, needle); - - if (needle_rptr == NULL) - return -1; - - /* Skip search string and whitespaces after it */ - needle_rptr += strlen(needle); - - num = strtol(needle_rptr, &needle_end, 10); - - if (needle_rptr == needle_end) - return -1; - - if (num == LONG_MIN || num == LONG_MAX) - return 0; - - return num > 0 ? num : 0; -} - -/** - * tap_version_present: - * @record: buffer with tap data - * @print_info: whether tap version should be printed or not - * - * Returns: - * 0 if not found - * 1 if found - */ -static int tap_version_present(char* record, bool print_info) -{ - /* - * "(K)TAP version XX" should be the first line on all (sub)tests as per - * https://kernel.org/doc/html/latest/dev-tools/ktap.html#version-lines - * - * but actually isn't, as it currently depends on the KUnit module - * being built-in, so we can't rely on it every time - */ - const char *version_rptr = strcasestr(record, "TAP version "); - char *cutoff; - - if (version_rptr == NULL) - return 0; - - /* Cutoff after newline character, in order to not display garbage */ - cutoff = strchr(version_rptr, '\n'); - if (cutoff) - cutoff[0] = '\0'; - - if (print_info) - igt_info("%s\n", version_rptr); - - return 1; -} - -/** - * find_next_tap_subtest: - * @fd: file descriptor - * @record: buffer used to read fd - * @is_builtin: whether KUnit is built-in or not - * - * Returns: - * 0 if there's missing information - * -1 if not found - * -2 if there are problems while reading the file. - * any other value corresponds to the amount of cases of the next (sub)test - */ -static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_builtin) -{ - const char *test_lookup_str, *subtest_lookup_str, *name_rptr; - long test_count; - char *cutoff; - - test_name[0] = '\0'; - test_name[BUF_LEN] = '\0'; - - test_lookup_str = " subtest: "; - subtest_lookup_str = " test: "; - - if (!tap_version_present(record, true)) - return -1; - - if (is_builtin) { - if (read(fd, record, BUF_LEN) < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("an error occurred while reading kmsg: %m\n"); - - return -2; - } - } - - name_rptr = strcasestr(record, test_lookup_str); - if (name_rptr != NULL) { - name_rptr += strlen(test_lookup_str); - } else { - name_rptr = strcasestr(record, subtest_lookup_str); - if (name_rptr != NULL) - name_rptr += strlen(subtest_lookup_str); - } - - if (name_rptr == NULL) { - if (!is_builtin) - /* We've probably found nothing */ - return -1; - igt_info("Missing test name\n"); - } else { - strncpy(test_name, name_rptr, BUF_LEN); - /* Cutoff after newline character, in order to not display garbage */ - cutoff = strchr(test_name, '\n'); - if (cutoff) - cutoff[0] = '\0'; - - if (read(fd, record, BUF_LEN) < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("unknown error reading kmsg (%m)\n"); - - return -2; - } - - /* Now we can be sure we found tests */ - if (!is_builtin) - igt_info("KUnit is not built-in, skipping version check...\n"); - } - - /* - * Total test count will almost always appear as 0..N at the beginning - * of a run, so we use it to reliably identify a new run - */ - test_count = lookup_value(record, ".."); - - if (test_count <= 0) { - igt_info("Missing test count\n"); - if (test_name[0] == '\0') - return 0; - if (log_to_end(IGT_LOG_INFO, fd, record, - "Running some tests in: %s\n", - test_name) < 0) - return -2; - return 0; - } else if (test_name[0] == '\0') { - igt_info("Running %ld tests...\n", test_count); - return 0; - } - - if (log_to_end(IGT_LOG_INFO, fd, record, - "Executing %ld tests in: %s\n", - test_count, test_name) < 0) - return -2; - - return test_count; -} - -/** - * parse_kmsg_for_tap: - * @fd: file descriptor - * @record: buffer used to read fd - * @test_name: buffer to store the test name - * - * Returns: - * 1 if no results were found - * 0 if a test succeded - * -1 if a test failed - * -2 if there are problems reading the file - */ -static int parse_kmsg_for_tap(int fd, char *record, char *test_name) -{ - const char *lstart, *ok_lookup_str, *nok_lookup_str, - *ok_rptr, *nok_rptr, *comment_start, *value_parse_start; - char *test_name_end; - - ok_lookup_str = "ok "; - nok_lookup_str = "not ok "; - - lstart = strchrnul(record, ';'); - - if (*lstart == '\0') { - igt_warn("kmsg truncated: output malformed (%m)\n"); - return -2; - } - - lstart++; - while (isspace(*lstart)) - lstart++; - - nok_rptr = strstr(lstart, nok_lookup_str); - if (nok_rptr != NULL) { - nok_rptr += strlen(nok_lookup_str); - while (isdigit(*nok_rptr) || isspace(*nok_rptr) || *nok_rptr == '-') - nok_rptr++; - test_name_end = strncpy(test_name, nok_rptr, BUF_LEN); - while (!isspace(*test_name_end)) - test_name_end++; - *test_name_end = '\0'; - if (log_to_end(IGT_LOG_WARN, fd, record, - "%s", lstart) < 0) - return -2; - return -1; - } - - comment_start = strchrnul(lstart, '#'); - - /* Check if we're still in a subtest */ - if (*comment_start != '\0') { - comment_start++; - value_parse_start = comment_start; - - if (lookup_value(value_parse_start, "fail: ") > 0) { - if (log_to_end(IGT_LOG_WARN, fd, record, - "%s", lstart) < 0) - return -2; - return -1; - } - } - - ok_rptr = strstr(lstart, ok_lookup_str); - if (ok_rptr != NULL) { - ok_rptr += strlen(ok_lookup_str); - while (isdigit(*ok_rptr) || isspace(*ok_rptr) || *ok_rptr == '-') - ok_rptr++; - test_name_end = strncpy(test_name, ok_rptr, BUF_LEN); - while (!isspace(*test_name_end)) - test_name_end++; - *test_name_end = '\0'; - return 0; - } - - return 1; -} - -/** - * parse_tap_level: - * @fd: file descriptor - * @base_test_name: test_name from upper recursion level - * @test_count: test_count of this level - * @failed_tests: top level failed_tests pointer - * @found_tests: top level found_tests pointer - * @is_builtin: whether the KUnit module is built-in or not - * - * Returns: - * 0 if succeded - * -1 if error occurred - */ -__maybe_unused -static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *failed_tests, - bool *found_tests, bool is_builtin) -{ - char record[BUF_LEN + 1]; - struct ktap_test_results_element *r; - int internal_test_count; - char test_name[BUF_LEN + 1]; - char base_test_name_for_next_level[BUF_LEN + 1]; - - for (int i = 0; i < test_count; i++) { - if (read(fd, record, BUF_LEN) < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("error reading kmsg (%m)\n"); - - return -1; - } - - /* Sublevel found */ - if (tap_version_present(record, false)) - { - internal_test_count = find_next_tap_subtest(fd, record, test_name, - is_builtin); - switch (internal_test_count) { - case -2: - /* No more data to read */ - return -1; - case -1: - /* No test found */ - return -1; - case 0: - /* Tests found, but they're missing info */ - *found_tests = true; - return -1; - default: - *found_tests = true; - - memcpy(base_test_name_for_next_level, base_test_name, BUF_LEN); - if (strlen(base_test_name_for_next_level) < BUF_LEN - 1 && - base_test_name_for_next_level[0]) - strncat(base_test_name_for_next_level, DELIMITER, - BUF_LEN - strlen(base_test_name_for_next_level)); - memcpy(base_test_name_for_next_level + strlen(base_test_name_for_next_level), - test_name, BUF_LEN - strlen(base_test_name_for_next_level)); - - if (parse_tap_level(fd, base_test_name_for_next_level, - internal_test_count, failed_tests, found_tests, - is_builtin) == -1) - return -1; - break; - } - } - - switch (parse_kmsg_for_tap(fd, record, test_name)) { - case -2: - return -1; - case -1: - *failed_tests = true; - - r = malloc(sizeof(*r)); - - memcpy(r->test_name, base_test_name, BUF_LEN); - if (strlen(r->test_name) < BUF_LEN - 1) - if (r->test_name[0]) - strncat(r->test_name, DELIMITER, - BUF_LEN - strlen(r->test_name)); - memcpy(r->test_name + strlen(r->test_name), test_name, - BUF_LEN - strlen(r->test_name)); - r->test_name[BUF_LEN] = '\0'; - - r->passed = false; - - pthread_mutex_lock(&results.mutex); - igt_list_add_tail(&r->link, &results.list); - pthread_mutex_unlock(&results.mutex); - - test_name[0] = '\0'; - break; - case 0: - r = malloc(sizeof(*r)); - - memcpy(r->test_name, base_test_name, BUF_LEN); - if (strlen(r->test_name) < BUF_LEN - 1) - if (r->test_name[0]) - strncat(r->test_name, DELIMITER, - BUF_LEN - strlen(r->test_name)); - memcpy(r->test_name + strlen(r->test_name), test_name, - BUF_LEN - strlen(r->test_name)); - r->test_name[BUF_LEN] = '\0'; - - r->passed = true; - - pthread_mutex_lock(&results.mutex); - igt_list_add_tail(&r->link, &results.list); - pthread_mutex_unlock(&results.mutex); - - test_name[0] = '\0'; - break; - default: - break; - } - } - return 0; -} - -/** - * igt_ktap_parser: - * - * This function parses the output of a ktap script and passes it to main thread. - */ -void *igt_ktap_parser(void *unused) -{ - char record[BUF_LEN + 1], *buf, *suite_name = NULL, *case_name = NULL; - struct igt_ktap_results *ktap = NULL; - int fd = ktap_args.fd; - IGT_LIST_HEAD(list); - int err; - - ktap = igt_ktap_alloc(&list); - if (igt_debug_on(!ktap)) - goto igt_ktap_parser_end; - - while (err = read(fd, record, BUF_LEN), err > 0) { - struct igt_ktap_result *r, *rn; - - /* skip kmsg continuation lines */ - if (igt_debug_on(*record == ' ')) - continue; - - /* NULL-terminate the record */ - record[err] = '\0'; - - /* detect start of log message, continue if not found */ - buf = strchrnul(record, ';'); - if (igt_debug_on(*buf == '\0')) - continue; - buf++; - - err = igt_ktap_parse(buf, ktap); - - /* parsing error */ - if (err && err != -EINPROGRESS) - goto igt_ktap_parser_end; - - igt_list_for_each_entry_safe(r, rn, &list, link) { - struct ktap_test_results_element *result = NULL; - int code = r->code; - - if (code != IGT_EXIT_INVALID) - result = calloc(1, sizeof(*result)); - - if (result) { - snprintf(result->test_name, sizeof(result->test_name), - "%s-%s", r->suite_name, r->case_name); - - if (code == IGT_EXIT_SUCCESS) - result->passed = true; - } - - igt_list_del(&r->link); - if (r->suite_name != suite_name) { - free(suite_name); - suite_name = r->suite_name; - } - if (r->case_name != case_name) { - free(case_name); - case_name = r->case_name; - } - free(r->msg); - free(r); - - /* - * no extra result record expected on start - * of parametrized test case -- skip it - */ - if (code == IGT_EXIT_INVALID) - continue; - - if (!result) { - err = -ENOMEM; - goto igt_ktap_parser_end; - } - - pthread_mutex_lock(&results.mutex); - igt_list_add_tail(&result->link, &results.list); - pthread_mutex_unlock(&results.mutex); - } - - /* end of KTAP report */ - if (!err) - goto igt_ktap_parser_end; - } - - if (err < 0) { - if (errno == EPIPE) - igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); - else if (errno != EINTR) - igt_warn("error reading kmsg (%m)\n"); - } - -igt_ktap_parser_end: - free(suite_name); - free(case_name); - - if (!err) - ktap_args.ret = IGT_EXIT_SUCCESS; - - results.still_running = false; - - if (ktap) - igt_ktap_free(ktap); - - return NULL; -} - -static pthread_t ktap_parser_thread; - -struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin) -{ - IGT_INIT_LIST_HEAD(&results.list); - pthread_mutex_init(&results.mutex, NULL); - results.still_running = true; - - ktap_args.fd = fd; - ktap_args.is_builtin = is_builtin; - ktap_args.ret = IGT_EXIT_FAILURE; - pthread_create(&ktap_parser_thread, NULL, igt_ktap_parser, NULL); - - return &results; -} - -void ktap_parser_cancel(void) -{ - pthread_cancel(ktap_parser_thread); -} - -int ktap_parser_stop(void) -{ - pthread_join(ktap_parser_thread, NULL); - return ktap_args.ret; -} diff --git a/lib/igt_ktap.h b/lib/igt_ktap.h index 6f8da3eab6..c422636bfc 100644 --- a/lib/igt_ktap.h +++ b/lib/igt_ktap.h @@ -27,8 +27,6 @@ #define BUF_LEN 4096 -#include - #include "igt_list.h" struct igt_ktap_result { @@ -45,24 +43,4 @@ struct igt_ktap_results *igt_ktap_alloc(struct igt_list_head *results); int igt_ktap_parse(const char *buf, struct igt_ktap_results *ktap); void igt_ktap_free(struct igt_ktap_results *ktap); -void *igt_ktap_parser(void *unused); - -typedef struct ktap_test_results_element { - char test_name[BUF_LEN + 1]; - bool passed; - struct igt_list_head link; -} ktap_test_results_element; - -struct ktap_test_results { - struct igt_list_head list; - pthread_mutex_t mutex; - bool still_running; -}; - - - -struct ktap_test_results *ktap_parser_start(int fd, bool is_builtin); -void ktap_parser_cancel(void); -int ktap_parser_stop(void); - #endif /* IGT_KTAP_H */ From patchwork Fri Sep 8 10:44:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377355 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25FA6EE57F1 for ; Fri, 8 Sep 2023 10:47:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 65A4F10E8B8; Fri, 8 Sep 2023 10:47:07 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9DB0E10E8B9; Fri, 8 Sep 2023 10:47:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170025; x=1725706025; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JnHWuNqrg719Ei4PdPu6rwQA/349CcrtKrTYDmGHO40=; b=VM0IllRi0XQUqPkvHYLmZsF5ScFR+8fBOaNer9+WcQMQG6WoPu1H0Isu gA2WYwTyz9Jl13IBR9ME7+iV+hRLYAou6Nu//lsONMbqynE3xqMN2GpQF pc+fOCn712QcadrjU6NVrns2/Nj1bo7Z1Gb7Lxo8xpfn2/pre+AFtG8CU wBywp12uGRuv5CYHqF/Yz405owurRRg/kIluyIdgjn0szZgTSVJZ5bkYt VkD3Pbc9KinfWJvjFl4EXfeBTi7SNmRFCyy82y4Cg0Muq8T5fa8vjIBKQ UdFtihcIxH3ykL1M7kCj/OQfaSAqzOoHH2KZo+Goo0/IKoEd3WUJYi2tS w==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922687" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922687" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531643" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531643" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:03 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:55 +0200 Message-ID: <20230908104438.125454-35-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 16/17] lib/kunit: Strip "_test" or "_kunit" suffix from subtest names X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" If a user (an IGT test) doesn't provide a subtest name when calling igt_kunit() then we now use the requested kernel module name as IGT subtest name. Since names of kunit test modules usually end with a "_test" or "_kunit" suffix, those parts of the names don't carry any useful information. Strip those suffixes from IGT subtest names. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 26 ++++++++++++++++++++++---- tests/drm_mm.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 46a6f81e73..ddd5499f5e 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -944,8 +944,29 @@ void igt_kunit(const char *module_name, const char *name, const char *opts) if (igt_ktest_init(&tst, module_name) != 0) return; - igt_fixture + /* + * If the caller (an IGT test) provides no subtest name then we + * take the module name, drop the trailing "_test" or "_kunit" + * suffix, if any, and use the result as our IGT subtest name. + */ + if (!name) { + name = strdup(module_name); + if (name) { + char *suffix = strstr(name, "_test"); + + if (!suffix) + suffix = strstr(name, "_kunit"); + + if (suffix) + *suffix = '\0'; + } + } + + igt_fixture { + igt_require(name); + igt_require(igt_ktest_begin(&tst) == 0); + } /* * We need to use igt_subtest here, as otherwise it may crash with: @@ -954,9 +975,6 @@ void igt_kunit(const char *module_name, const char *name, const char *opts) * proper namespace for dynamic subtests, with is required for CI * and for documentation. */ - if (name == NULL) - name = module_name; - igt_subtest_with_dynamic(name) __igt_kunit(&tst, opts); diff --git a/tests/drm_mm.c b/tests/drm_mm.c index 9a8b3f3fcb..e6ba224745 100644 --- a/tests/drm_mm.c +++ b/tests/drm_mm.c @@ -29,123 +29,123 @@ * Feature: mapping * Run type: FULL * - * SUBTEST: drm_mm_test + * SUBTEST: drm_mm * - * SUBTEST: drm_mm_test@align + * SUBTEST: drm_mm@align * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@align32 + * SUBTEST: drm_mm@align32 * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@align64 + * SUBTEST: drm_mm@align64 * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@bottomup + * SUBTEST: drm_mm@bottomup * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@color + * SUBTEST: drm_mm@color * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@color_evict + * SUBTEST: drm_mm@color_evict * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@color_evict_range + * SUBTEST: drm_mm@color_evict_range * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@debug + * SUBTEST: drm_mm@debug * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@evict + * SUBTEST: drm_mm@evict * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@evict_range + * SUBTEST: drm_mm@evict_range * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@frag + * SUBTEST: drm_mm@frag * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@highest + * SUBTEST: drm_mm@highest * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@init + * SUBTEST: drm_mm@init * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@insert + * SUBTEST: drm_mm@insert * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@insert_range + * SUBTEST: drm_mm@insert_range * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@lowest + * SUBTEST: drm_mm@lowest * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@replace + * SUBTEST: drm_mm@replace * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@reserve + * SUBTEST: drm_mm@reserve * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@sanitycheck + * SUBTEST: drm_mm@sanitycheck * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt * Test category: GEM_Legacy * - * SUBTEST: drm_mm_test@topdown + * SUBTEST: drm_mm@topdown * Category: Infrastructure * Description: drm_mm range manager SW validation * Functionality: DRM memory mangemnt From patchwork Fri Sep 8 10:44:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13377358 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 72128EE57EF for ; Fri, 8 Sep 2023 10:47:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BB7D710E04B; Fri, 8 Sep 2023 10:47:13 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id C1B0D10E8B9; Fri, 8 Sep 2023 10:47:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694170027; x=1725706027; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JKnf7psVzbr57Mq5EFJBAPM3SNWMV0ma7c+dpTqUf1g=; b=SvIxcc0Ond3abC9UStERh2AYpJDTAHTbvqy5Ig3ez9aopT2CI5nQAH0v Ybx1bCytlmajhQY9UneFpC5lrwqbou27JHYnGjG0SzSp5nkQy4jGAWixh 9fFWF8lJSu1KF2wfgbN1A23ov8J0VbwL20q7g+b0g9wTgmWCmWxUy7jqo yB6p4c8DSAbXe8WaOMkhTwSvA0IO9C/rzqqSH6iR9rX0h77ljcbN1V01H 1RGnUROYaCixHXsMOCdN28FijOJ5oP+bR0w4f/2SchfJWHRD+Gm3WL19o LazNmZOeVbjdNOjxQbUMSlGl8Dg1ldw0zKHeuxGK5uFb8zddDvQhGhL9Z g==; X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="357922695" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="357922695" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10826"; a="812531648" X-IronPort-AV: E=Sophos;i="6.02,236,1688454000"; d="scan'208";a="812531648" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.28.201]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Sep 2023 03:47:05 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Fri, 8 Sep 2023 12:44:56 +0200 Message-ID: <20230908104438.125454-36-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> References: <20230908104438.125454-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 17/17] lib/kunit: Omit suite name prefix if the same as subtest name X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: intel-gfx@lists.freedesktop.org, =?utf-8?q?Dominik_Karol_Pi=C4=85tkowski?= , Isabella Basso , Mauro Carvalho Chehab , intel-xe@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Kunit test modules usually contain one test suite, named after the module name with the trailing "_test" or "_kunit" suffix omitted. Since we follow the same convention when we derive subtest names from module names, there is a great chance that those two names match. Take this into account when composing names for IGT dynamic sub-subtest names and drop the leading test suite name component when it is the same as subtest name. Signed-off-by: Janusz Krzysztofik --- lib/igt_kmod.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index ddd5499f5e..bd4305482b 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -822,7 +822,8 @@ static void kunit_result_free(struct igt_ktap_result *r, * * Returns: IGT default codes */ -static void __igt_kunit(struct igt_ktest *tst, const char *opts) +static void +__igt_kunit(struct igt_ktest *tst, const char *name, const char *opts) { struct modprobe_data modprobe = { tst->kmod, opts, 0, }; char *suite_name = NULL, *case_name = NULL; @@ -866,7 +867,11 @@ static void __igt_kunit(struct igt_ktest *tst, const char *opts) r = igt_list_first_entry(&results, r, link); - igt_dynamic_f("%s-%s", r->suite_name, r->case_name) { + igt_dynamic_f("%s%s%s", + strcmp(r->suite_name, name) ? r->suite_name : "", + strcmp(r->suite_name, name) ? "-" : "", + r->case_name) { + if (r->code == IGT_EXIT_INVALID) { /* parametrized test case, get actual result */ kunit_result_free(r, &suite_name, &case_name); @@ -976,7 +981,7 @@ void igt_kunit(const char *module_name, const char *name, const char *opts) * and for documentation. */ igt_subtest_with_dynamic(name) - __igt_kunit(&tst, opts); + __igt_kunit(&tst, name, opts); igt_ktest_end(&tst);