From patchwork Mon Sep 18 13:42: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: 13389664 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 F1309C46CA1 for ; Mon, 18 Sep 2023 13:52:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4096310E0FA; Mon, 18 Sep 2023 13:52:30 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 901D010E011; Mon, 18 Sep 2023 13:52:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045146; x=1726581146; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MuSuOOjb/VKbNbYghwTiXwNW4CnFRehbzIFgf7NNhFc=; b=EjEwstMMJ0ZUw66i51AmUagGYUIDZo3vXhUHb0pwtBDRIJgpLvDFK5HY e/IBVv5risplT7TMih75RaMDVfXmqL7VyxO2HSWtd9qxbKMhIR1DjkDIp 9oQrKopuC9aMHqTr1CSPWTPJ6UxQJk6Nn4qM90Vk7oGc9MMrUGTcNWvlP THUg9bbtHy9xSNR63wd1llFH+NO25RtYTq4mA5FHBoI3ZLUfCypa0Haav q6s57X/x5/GZTPTRdWaaEC37//ht050E+29kw+5ZD+3SgqbwhJH9zm7co 0JbLXd7iEvXCin/f1H69cSCAxp4uk3ZdwR9LHJHok6RQTQaECYSzE5+Vs g==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969494" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969494" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030446" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030446" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:24 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:51 +0200 Message-ID: <20230918134249.31645-20-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 kmsg data. While my idea was wrong because each read of raw data from /dev/kmsg always returns one full log record that always ends 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 raw 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 Acked-by: Mauro Carvalho Chehab --- 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 Mon Sep 18 13:42:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389665 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 EC072CD13D2 for ; Mon, 18 Sep 2023 13:52:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC46C10E18E; Mon, 18 Sep 2023 13:52:32 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id BDA9210E18E; Mon, 18 Sep 2023 13:52:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045148; x=1726581148; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Iu15LpajJeFsdcvmrO2uBd2L8V2RaUiH1BfPdkx8lqU=; b=OyrOXz/AV1nhYTcu6SCNjBgUrCm6Uw59rS0O0lJq4q1xXY2iJqQcwpge ZqjElz1KOtTwB3PxZlzdJgNnXvxgV7LSjtmP5v0kGpmv8XvBJ+GYU/sWl hjONKOkcreg7bT5AJEqRLHLocAUHTwigGkBANE81guU4YVC/RVt2IyaYk zUmeA0UvlfEF9Y7JnH0RGtQ/hy1YVD1O/rD6bnM7pcruA8dTB3s2mV0jq ptW2bN1aTe9y+YBVoScYGG6j6ePIAV/2IgSviTmxX/f4qJ2hQVjuWiuU+ l5FypHXhszB5CPDYNKTZEEzPPatyZsV1u70GoYaXWxKliq89SiafbGS3H Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969507" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969507" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030453" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030453" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:26 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:52 +0200 Message-ID: <20230918134249.31645-21-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Acked-by: Mauro Carvalho Chehab --- 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 Mon Sep 18 13:42: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: 13389666 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 6E822CD37B0 for ; Mon, 18 Sep 2023 13:52:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C0A1B10E289; Mon, 18 Sep 2023 13:52:33 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7EA6F10E18E; Mon, 18 Sep 2023 13:52: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=1695045151; x=1726581151; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=t6IqFNp2j8xWD+lDsrlKMG9k1FdJ/Q8PzsqPz7SegME=; b=CMONc+0DSWsjtYqzS9NrYIOvfgRYZAELAcfrCryjDR9ySoSkL6FV721L 7C9ISfDx9B5Wt++PDTH7cE6330yZd8tvfiM3OtjcleaKEMo58xuGd7W0m X6oPTntnneW0kyuCaFaCdMGy4F7qFBKFOYs4fpgyMhwhGeNJrKwu+cXN4 HpJxemrnG55PWI6ZOQwLHIyEvylyeUdkXOQHXLGUS9XbLCmbUSvAvZoNu xnojjhaVyj1tXK62MJm2hjmixQcRvqgIQ+9YS22WDVZu0h4lRdOrGoR66 NP9aB//sWszVRIPszornOQR3RgjgzZT7JUZCG6eK5h30djSvu3DAi7kM9 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969520" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969520" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030465" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030465" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:28 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:53 +0200 Message-ID: <20230918134249.31645-22-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 Mon Sep 18 13:42:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389667 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 F20C8CD13D2 for ; Mon, 18 Sep 2023 13:52:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 47CBE10E290; Mon, 18 Sep 2023 13:52:37 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id CC79B10E28A; Mon, 18 Sep 2023 13:52: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=1695045153; x=1726581153; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QjsQJot0t2pE6OIPMhGvT3ZJTsfAAoVMGx+qnjrzYjU=; b=DWLyTfdoxA5ptJpmDvuRlEZX2xWgNKDopBfUuu2sZF+0SJxDO/tYVmBw 1ri50MDGZFsu/2viwUQ12sMi++1+Pm/kvk/TXc6ur8akEKz1oUNHSvh3J tCTilamV60oxpoOvxcNFEhVY9z9PWQIu1Jvd+ZP6VYwZJXpHvgLPnr0Z3 vLddl91yiRyvuqkLcrbrRKEkgyea2SVrASqfc+2LuDNcmIHUPeWMiXCDs 1aATOpEnQ04A88jJHq31XSDW0kRDgwXQnLbaXNj9glM8XXus1IBHrgWBN Q/Gy8PZGP2WoYtqJLKYIP0F6EJeqQ+Sg+bDivGkcHMA7LvkgOrguOaGgI g==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969530" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969530" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030474" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030474" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:31 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:54 +0200 Message-ID: <20230918134249.31645-23-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 Mon Sep 18 13:42: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: 13389668 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 B9D07CD37B0 for ; Mon, 18 Sep 2023 13:52:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A4C4E10E291; Mon, 18 Sep 2023 13:52:38 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 297E410E297; Mon, 18 Sep 2023 13:52:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045156; x=1726581156; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+PcZiED3S5QXxvR34S9yibq5ZQTz2DMepfCD1+gSh6w=; b=WB26nchX2SKL5a2BluyP/zoHnDrLXpugfyueUWxeB2lOnc3d9/tu648E 4ZCay5Fhd03FvDKJ0hmIRdZ/M03wC0OIGQ7dsvx6Lb8IS6AaneY/ot1WC +ZwJFrygnBtP7eKzC9Hk+6cbUKr5b9i/VpZ+L8CdrA7+5x4c7Vfa6SdP5 TR9d+0GvHFfp4E3rSD+/gbx2Vz205UUMOgAf1T3pi4JFP88/6fClRYZsF ibgEDw/bveAKX0VtAabxPnemWTqroCLlZJ5LcBXWqqG5CiKVLZAsFCN/6 LKxY+aM0+8Wj2TXhQI0zJ3hlehFcfE4CqWb8EuquhRa34UWCuamWg2End Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969542" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969542" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030486" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030486" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:33 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:55 +0200 Message-ID: <20230918134249.31645-24-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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. v2: Also call igt_skip() on igt_ktest_init() failure (Mauro), but then, initialize local tst structure when declaring it to avoid freeing a random pointer from igt_ktest_fini() when only listing subtests, - call igt_ktest_end() from igt_fixture so it is not unnecessarily called when only listing subtests. Signed-off-by: Janusz Krzysztofik Cc: Mauro Carvalho Chehab Acked-by: Mauro Carvalho Chehab Acked-by: Mauro Carvalho Chehab --- lib/igt_kmod.c | 76 +++++++++++++++----------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 1d1cd51170..063e4c12db 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); - } + igt_skip_on_f(tst->kmsg < 0, "Could not open /dev/kmsg\n"); - if (tst.kmsg < 0) { - igt_warn("Could not open /dev/kmsg\n"); - fail = true; - goto unload; - } - - 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 = { .kmsg = -1, }; + + + igt_fixture { + igt_skip_on(igt_ktest_init(&tst, module_name)); + igt_skip_on(igt_ktest_begin(&tst)); + } + /* * 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,12 @@ 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_fixture + igt_ktest_end(&tst); + + igt_ktest_fini(&tst); } static int open_parameters(const char *module_name) From patchwork Mon Sep 18 13:42: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: 13389669 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 7FD81CD13D2 for ; Mon, 18 Sep 2023 13:52:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C500E10E011; Mon, 18 Sep 2023 13:52:40 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7A9A810E04D; Mon, 18 Sep 2023 13:52:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045158; x=1726581158; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iCQ+MWsQZNQh+UO6eDz4m7sv5WWrAMfmwamZITYgPys=; b=mWy6TRJFM2s9TZz/99bJqHdh9VArRoPcuTsKwhJgjCLV1Uf7/8UiHXYG OdTAvuIGHNBrRy60/9eSVmW0wxxaNU4qTTtg1/7LdICMNltxRLXm6TsS+ IMVpWDSs0BRXS6WesjIZ2LUF9Gth34qE0ORVZ2/6Pkhj+pprjJMOpZDG6 xBHDEiNri0n7Af2Gd5sC5Yt/BynP/A3Z8Nc3n+56YdqM3zrroWPdeBw6Z dHLb0/F1uG/MdoqwrckTSU06TwcwsMwkUnSggafgnJ19YYHT3uh5hz2NX HvroDe4+cX/9XuMLBO4RLr/bUWGRPlfmWhIIfSRdrUldbMd9BGpeSonmy w==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969552" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969552" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030496" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030496" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:36 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:56 +0200 Message-ID: <20230918134249.31645-25-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 Mon Sep 18 13:42:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389670 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 EE88BCD13DD for ; Mon, 18 Sep 2023 13:52:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C28A210E285; Mon, 18 Sep 2023 13:52:44 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id E4E3910E04D; Mon, 18 Sep 2023 13:52:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045161; x=1726581161; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HT6k5N/fzNG2HG1FT7wFBXyejK99HVsv9ycsPl1LUiQ=; b=GNWzAhE6+t3nKjxKN2o0bDA51hT1ZOKEcdHdKYJrJtSqxMagDvpf2VYY bXIp94hWLDll9r6XGYXJR79s+aK9wE4wDNS24od3pjuuSGLb3mnZfdNU8 MK8Z4OKfrOSwDHfz28Bmid+MErO4yqZdENHvX2lUAt7mbJTnZ2hQ58aNA koxZUiO11yThQ6METSt1SaLIxlyzEXpR5gLxNkxLN0Kf1SRumal4d/ZtP d1u0VnT1Rfkw4dYNkHI3lwPRKu5ewhNdLF/PZeFOXgG6vWl3ryINPN+Ng emGK8F6G+PDxq2ZR504yNHH7iSz4/K+3y8snPfmpt+QBi7yQOFz4xYbww g==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969563" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969563" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030503" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030503" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:38 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:57 +0200 Message-ID: <20230918134249.31645-26-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 07/17] lib/ktap: Drop checks for EINTR on read() failures 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 EINTR failures that may occur during read() and we continue reading the data. No explanation has been provided on what that could be needed for. Since we use default SIGINT signal handler, read() should never fail with errno set to EINTR on user interrupt, only the whole process should be terminated. Drop checks for errno == EINTR as not applicable. v2: Drop handling of EINTR completely, update commit message and descripion. Signed-off-by: Janusz Krzysztofik Cc: Mauro Carvalho Chehab Acked-by: Mauro Carvalho Chehab --- lib/igt_ktap.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 84fb13218f..ce07f9aed7 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -66,9 +66,6 @@ static int log_to_end(enum igt_log_level level, int fd, return -2; } - if (errno == EINTR) - continue; - if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -188,9 +185,6 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ return -2; } - if (errno == EINTR) - continue; - if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -232,9 +226,6 @@ static int find_next_tap_subtest(int fd, char *record, char *test_name, bool is_ return -2; } - if (errno == EINTR) - continue; - if (errno == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -387,9 +378,6 @@ static int parse_tap_level(int fd, char *base_test_name, int test_count, bool *f return -1; } - if (errno == EINTR) - continue; - if (errno == EAGAIN) /* No records available */ continue; @@ -540,9 +528,6 @@ igt_ktap_parser_start: /* No records available */ continue; - if (errno == EINTR) - continue; - 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; From patchwork Mon Sep 18 13:42:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389671 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 CCF3FC46CA1 for ; Mon, 18 Sep 2023 13:52:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 69CD010E2B4; Mon, 18 Sep 2023 13:52:45 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1F3EF10E190; Mon, 18 Sep 2023 13:52:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045163; x=1726581163; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4SbNkztvh9Ng9k2Efq2e84/O2G1a20Hqjkg7j5DUPKE=; b=VuXQwoEk9iwY5z4jaCc49kKgz30Ywiu2ZTqXRLvDrAMYysT2h9LrU1pF Mok+XIVz2P8hQSpVV0uZBLPwR2eHvXX7wfVtPnFQUfQd76V6gLtO8Wzmb RWRHoObbew5iTGeqlYxPQDnhH92TzcTTMCYXt1FZw+DoW9LTvNiTH8sWU xpVPbK3WMpkN4zc++Yra3LdhHCU0qJ5siQOVIatQBg4b2+rObqZl3pd3s U+mPJi0xMqj0Ikf0dt1UfE+X4Bx6nMh4Y3A8hh9mXIKlDGRj7opVFQObt 87LjIPHzyGB64W/c0N9UuSV8pNsDXChrcb1r8dT0Bp8V5hi+anN7GLaPi Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969604" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969604" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030516" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030516" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:40 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:58 +0200 Message-ID: <20230918134249.31645-27-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 063e4c12db..7392276401 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 ce07f9aed7..0db42d1243 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -587,6 +587,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 Mon Sep 18 13:42:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389672 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 1AC49C46CA1 for ; Mon, 18 Sep 2023 13:52:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5DFB710E2C2; Mon, 18 Sep 2023 13:52:48 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4145B10E2A8; Mon, 18 Sep 2023 13:52:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045165; x=1726581165; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wVtUGzS/C/rlpHDTOGmg6+f8L2dKaVPMHK1N123GdfI=; b=VmvS/Gz/AAbyCvs9PkmjM79sntOEnGuaObf7Wiey9bqLs5yiaon7tBb/ z68lHqvcUgIiXqTDPIphe5Y1SphP6EwdjHLgL7jQJs85sLxD+A8rafwJy MZhoOMZm4z6feyJ8uoRsSO7uR+8D/BkJOVs1BIuBcghlq/vWXpkHphD5a GGINKSea9JvKzH8mITAwJQcxcFovfVpHnx7zdnTnXU8Kc32vwFqPYRLCi 6bDYwlOjX8SMZvPRuPAqCTnEWH0MAsP+Z5kNDIa2CpudQUpxY/FJSQDE4 026i5Mhx9x5cz11nvsiaYF0OIHNZekg9BddXyyPvHvF0F26lD21ovxzM5 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969644" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969644" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030536" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030536" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:42 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:42:59 +0200 Message-ID: <20230918134249.31645-28-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- lib/igt_ktap.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/lib/igt_ktap.c b/lib/igt_ktap.c index 0db42d1243..5bc5e003d7 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 == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -180,11 +174,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 == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -221,11 +210,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 == EPIPE) { igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); return -2; @@ -373,11 +357,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 == EAGAIN) /* No records available */ continue; @@ -511,19 +490,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; @@ -580,7 +551,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); @@ -589,13 +559,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 Mon Sep 18 13:43:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389673 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 512BDCD13D8 for ; Mon, 18 Sep 2023 13:52:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B0A2D10E2C3; Mon, 18 Sep 2023 13:52:50 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 91ABE10E2C2; Mon, 18 Sep 2023 13:52:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045167; x=1726581167; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Fmai3mLemIy5DqvBqQCcRibTf+LUWjn/vpeTdT82tpY=; b=jSHnTtGj772z+sstCNlu7XewQN2uDWZ+k9XgdAV78huNBM5yl1Te1LLO V3FXD6JtI+E+tWKFGjDJyEd5E1bHLOa5LlUa+jhNEwEfcxwfQteUEmPdr Ztvm5GfHHQ5/e5leIgl81kwU4/vhPNCemJRDgvec91VxdX45V1tihGZ0d s4o3cHkZPMIhEp9Ip686HjcPyGA+LXp0ypqC1OVkGDPsDC7IO5C64k6W/ cHKdjzYKY2jUxo17oC7bP3iTMpkU2zPap9BsMpnxt6Ye9uuG+g87t7VCs QzfltXNjC84Myz1UDihpH9/3UybV9/YYmfoLRpEj+mAKecK9jRhFO5NRb w==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969657" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969657" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030546" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030546" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:45 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:00 +0200 Message-ID: <20230918134249.31645-29-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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. While being at it, fix read errors other than EPIPE likely unintentionally ignored when reading first line of KTAP data. v2: Drop EINTR handling as not applicable since SIGINT default signal handler kills the whole process anyway, - update commit description to also mention read error handling fix. Signed-off-by: Janusz Krzysztofik Acked-by: Mauro Carvalho Chehab # v1 Reviewed-by: Mauro Carvalho Chehab --- lib/igt_kmod.c | 7 +++++- lib/igt_ktap.c | 66 +++++++++++++++++--------------------------------- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 7392276401..96240543a7 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 5bc5e003d7..282e44176e 100644 --- a/lib/igt_ktap.c +++ b/lib/igt_ktap.c @@ -59,17 +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 == 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; - } - - if (errno == EAGAIN) - /* No records available */ - continue; + else + igt_warn("an error occurred while reading kmsg: %m\n"); - igt_warn("kmsg truncated: unknown error (%m)\n"); return -2; } @@ -173,17 +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 == 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 + 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; } } @@ -209,17 +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 == 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; - } - - if (errno == EAGAIN) - /* No records available */ - continue; + else + igt_warn("unknown error reading kmsg (%m)\n"); - igt_warn("kmsg truncated: unknown error (%m)\n"); return -2; } @@ -356,17 +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 == 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 + igt_warn("error reading kmsg (%m)\n"); - igt_warn("kmsg truncated: unknown error (%m)\n"); return -1; } @@ -494,15 +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 == 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 + 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 Mon Sep 18 13:43:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389675 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 C9ED5C46CA1 for ; Mon, 18 Sep 2023 13:52:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E00D10E2B1; Mon, 18 Sep 2023 13:52:56 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id CCA0E10E2C3; Mon, 18 Sep 2023 13:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045169; x=1726581169; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Xk5x1k/33qi2QectDJlPg2OZ13MAVe/dMUo+KUPEb18=; b=X6X99oRoOLEIRacWa9LVeXqDO1zmi3ih52+lZJCtfSsHENRJDWng46hs tFkGJlNh822/JhvVn7/a49/7B6Kx/ZO9coT9rIFbbBq6DCwNnC56MUwYU Pm8hqwRjx78qEsjn62CmMMt1K4qQTpVNM+H5e5+sp8CaNY6sRscw07Jtt hIwkgzBg/ya3MrzQBHBQj+yHAnBXoxit3mCFpoHNN/Pqbs/Uj26N9FQeZ jbralXndER+yKZNGbc+neBs9rtGKgZ9bCVnbb6eKOEDNE2NiCLhoE+vUb K+hVFPE5FG/TyKgg2iZ9awAOwKK738K4fln5PKOoGzUDFrqWIHLB8SEMQ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969669" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969669" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030554" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030554" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:47 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:01 +0200 Message-ID: <20230918134249.31645-30-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 96240543a7..77fc971f8f 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 Mon Sep 18 13:43:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389674 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 26C10CD13D2 for ; Mon, 18 Sep 2023 13:52:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7F1D410E2C8; Mon, 18 Sep 2023 13:52:54 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3947810E2C8; Mon, 18 Sep 2023 13:52: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=1695045172; x=1726581172; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=64vl/XJ4eoGpmfquq2Tw92Bse/XModQe6DKHUxvq6Xw=; b=Gk312A6JNsHL2IPUZsmN1tZvfbCyv+ggFsT4Lph5ODwClWrhyWq9Axtt i1mFYS1fdlNMGlyl4b1fhOMTLIVP9WqB3nIVyZ3bQIcI/TjSf1Xg/Qr6a l1CKxYVuyh9S2MfU32PDbQNjS64aZotAdh2HTDuGhHKVmUQ9y2aYaeMhI Qp3FxndU5etQRp1OHADjQQWmgfSIstTyItzWnwKRuBjZF1gSSprnHCJam qmXABNSFjaRYHnum8OYQnN3M+eN0rTKGxpiCPTvswUOW5uwanaw2heThP +NJkRu5xuNHAmt7g4OqkBmzld7bDJNZxn5rSAwyEyh3ZxVw9ngYo5pHSS A==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969686" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969686" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030561" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030561" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:49 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:02 +0200 Message-ID: <20230918134249.31645-31-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Acked-by: Mauro Carvalho Chehab --- 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 77fc971f8f..2941524bb4 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 282e44176e..c64323d9b4 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 Mon Sep 18 13:43:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389677 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 50574CD37B0 for ; Mon, 18 Sep 2023 13:53:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC39E10E2D0; Mon, 18 Sep 2023 13:52:59 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id DD41B10E2C9; Mon, 18 Sep 2023 13:52:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045174; x=1726581174; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Oq8n/j5RRkAHxps96x2r7QvnC6HIHJ+W4gQmVdvrkYI=; b=Ro7cq5KY5JFRIleiCcYaTo8STgvJZt21MIDOZmbT3hNLPKKbhg2OxPbA GwdQOirfM516e5LVXw+QJkbSkm16jFW37OlxEpVRwJoGX+qb+Fnicb+ny ycwaEYhZ/OThfwXVsWeUOHQD3lW6GbQFEvC2307UXifsUnwZIzKNHUK1S 2/WBjvQpuOr2/2oX+9dcUW6A6YOX759y6QBkfMfREX6ORKg3iv7WnuSRX onbzhL/Row6Q1wZJ3lRfzdiJIhg115yB6Cxo6S3HjA/iZAr+3tWkrRhJ9 R5cmgwbhsOBw9wEptslsA0WF+bTbRUhD3aQVYn24Yi9wsij8PYcgF+/HC Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969701" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969701" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030570" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030570" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:52 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:03 +0200 Message-ID: <20230918134249.31645-32-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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: - works only with built-in kunit, can't parse KTAP output if modular, - 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, - subtest names mostly consist of kunit suite name and kunit test case name but not always, sometimes the first component is omited, - 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. v2: Fix incorrect and missing includes in the test source file, - add license and copyright clauses to the test source file. Signed-off-by: Janusz Krzysztofik Acked-by: Mauro Carvalho Chehab --- lib/igt_ktap.c | 422 ++++++++++++++++++++++++++++++++---- lib/igt_ktap.h | 15 ++ lib/tests/igt_ktap_parser.c | 246 +++++++++++++++++++++ lib/tests/meson.build | 1 + 4 files changed, 645 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 c64323d9b4..5eac102417 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 - 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 + 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..6357bdf6a5 --- /dev/null +++ b/lib/tests/igt_ktap_parser.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: MIT +/* +* Copyright © 2023 Intel Corporation +*/ + +#include +#include +#include +#include + +#include "igt_core.h" +#include "igt_ktap.h" +#include "igt_list.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 Mon Sep 18 13:43:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389676 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 AC0CDC46CA1 for ; Mon, 18 Sep 2023 13:52:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0B98910E2CF; Mon, 18 Sep 2023 13:52:59 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id F1C6010E190; Mon, 18 Sep 2023 13:52: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=1695045177; x=1726581177; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7wnjMBn8hyh4pVg0G+mXr24gz0YOiaSNgk9ieuXW9c0=; b=Rsgo8AbqjW6WMNC2n+u/rr+CAwBgyTgFkbmMYHj4WCAvACEdCO32BHso v/hPHWU+jBom+aFSNIDROub4BdFOpRhxvhAehpPGQlEF5c3JClYZIFUhb 3UCljEX1BifZi0tTkGOLsCib8WWD8CSyThmbstrhng1QXrdCBZ/1PbtPJ dRxJTyrfECbCY9Z+Zdns43+m5C1EWtT5s3hcIr2TifangBOsriQabxdHG gNKhTeZCDBYal6kn+XRBjAJ7L5TRvwnEU81t8tAxJGzLC1dC/+XDjfQ0I Vt+Vmo9+DvXQ2mG1DKD4SR7d2xkLKYd0YSf/UwAUA1lJfaGAaPwKH5pMh w==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969716" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969716" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030578" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030578" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:54 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:04 +0200 Message-ID: <20230918134249.31645-33-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Acked-by: Mauro Carvalho Chehab --- 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 2941524bb4..8fbd274ccf 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 Mon Sep 18 13:43:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389678 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 BF116CD37B0 for ; Mon, 18 Sep 2023 13:53:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 44C4610E2C6; Mon, 18 Sep 2023 13:53:04 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6A72010E190; Mon, 18 Sep 2023 13:53: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=1695045180; x=1726581180; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yqUVrwLlQRiqjdq7Ad9EnrHXhqB07KsLH2dIYLVxW/s=; b=ku6/Yr5dj9yfkTeGWf0TkP9XQvLJXTYh4cnDM28PlxMdZbFkwo2Z3nwI rMItE4/5tzK9xLegc27+p6L2VDffhkEP6ADW0Kx7aLagliTHKVxUzsuuj Mq+D6bI2SpGVGIDZb/3Np7dT8P1arRVshwHA9hSn5LXu8P3Hm5bZh+GYF qnI5bkMUY29QJGOdworoitQqHqJ2xWVetxbrpin7xT8aAi+Wt2Bx9u+UR HJnAMwbhB5bmNhcj6A061bo12bjtcpyirXLz5kt/3JyA19twfdRgsV4/R YQNGAnGVafYoZOka0xEcyfuz3cek5btA8Z3h+HLw/QHukJS0ivJ+TesRh Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969732" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969732" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:53:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030587" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030587" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:52:57 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:05 +0200 Message-ID: <20230918134249.31645-34-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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. v2: Interrupt blocking read() on modprobe failure. Signed-off-by: Janusz Krzysztofik Acked-by: Mauro Carvalho Chehab --- lib/igt_kmod.c | 208 ++++++++++++++---- lib/igt_ktap.c | 568 ------------------------------------------------- lib/igt_ktap.h | 22 -- 3 files changed, 166 insertions(+), 632 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 8fbd274ccf..7fa5b4aa80 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" @@ -748,20 +751,109 @@ void igt_kselftest_get_tests(struct kmod_module *kmod, } struct modprobe_data { + pthread_t parent; struct kmod_module *kmod; const char *opts; int err; + pthread_mutex_t lock; + pthread_t thread; }; static void *modprobe_task(void *arg) { struct modprobe_data *data = arg; + int err; + + err = modprobe(data->kmod, data->opts); - data->err = modprobe(data->kmod, data->opts); + if (err) { + while (pthread_mutex_trylock(&data->lock) == EBUSY) + pthread_kill(data->parent, SIGCHLD); + + data->err = err; + pthread_mutex_unlock(&data->lock); + } return NULL; } +static void kunit_sigchld_handler(int signal) +{ + return; +} + +static int kunit_kmsg_result_get(struct igt_list_head *results, + struct modprobe_data *modprobe, + int fd, struct igt_ktap_results *ktap) +{ + struct sigaction sigchld = { .sa_handler = kunit_sigchld_handler, }; + char record[BUF_LEN + 1], *buf; + unsigned long taints; + int ret; + + do { + if (igt_kernel_tainted(&taints)) + return -ENOTRECOVERABLE; + + pthread_mutex_lock(&modprobe->lock); + if (!pthread_tryjoin_np(modprobe->thread, NULL) && + modprobe->err) { + pthread_mutex_unlock(&modprobe->lock); + return modprobe->err; + } + + sigaction(SIGCHLD, &sigchld, NULL); + ret = read(fd, record, BUF_LEN); + sigaction(SIGCHLD, NULL, NULL); + pthread_mutex_unlock(&modprobe->lock); + + if (!ret) + return -ENODATA; + if (ret == -1) + return -errno; + + igt_assert_lt(0, ret); + + /* 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; + } while (igt_list_empty(results)); + + 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 @@ -773,11 +865,12 @@ 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; - pthread_t modprobe_thread; + struct modprobe_data modprobe = { pthread_self(), tst->kmod, opts, 0, + PTHREAD_MUTEX_INITIALIZER, }; + char *suite_name = NULL, *case_name = NULL; + struct igt_ktap_result *r, *rn; + struct igt_ktap_results *ktap; + IGT_LIST_HEAD(results); unsigned long taints; int flags, ret; @@ -787,62 +880,93 @@ 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, + 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; - - if (!pthread_tryjoin_np(modprobe_thread, NULL) && modprobe.err) { - ktap_parser_cancel(); + do { + ret = kunit_kmsg_result_get(&results, &modprobe, + tst->kmsg, ktap); + if (igt_debug_on(ret && ret != -EINPROGRESS)) break; - } - if (igt_kernel_tainted(&taints)) { - ktap_parser_cancel(); - pthread_cancel(modprobe_thread); + if (igt_debug_on(igt_list_empty(&results))) break; - } - pthread_mutex_lock(&results->mutex); - if (igt_list_empty(&results->list)) { - pthread_mutex_unlock(&results->mutex); - continue; - } + 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; + + igt_assert(igt_list_empty(&results)); + + ret = kunit_kmsg_result_get(&results, &modprobe, + tst->kmsg, ktap); + if (ret != -EINPROGRESS) + igt_fail_on(ret); - result = igt_list_first_entry(&results->list, result, link); + igt_fail_on(igt_list_empty(&results)); - igt_list_del(&result->link); - pthread_mutex_unlock(&results->mutex); + r = igt_list_first_entry(&results, r, link); - igt_dynamic(result->test_name) { - igt_assert(READ_ONCE(result->passed)); + 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 (!pthread_tryjoin_np(modprobe_thread, NULL)) + if (ret != -EINPROGRESS) + igt_assert_eq(ret, 0); + + if (!pthread_tryjoin_np(modprobe.thread, NULL)) igt_assert_eq(modprobe.err, 0); igt_fail_on(igt_kernel_tainted(&taints)); } - free(result); - } + kunit_result_free(r, &suite_name, &case_name); + + } while (ret == -EINPROGRESS); - pthread_join(modprobe_thread, NULL); + 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 5eac102417..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 - 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 - 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 - 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 - 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 - 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 Mon Sep 18 13:43:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389679 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 073CBCD13D8 for ; Mon, 18 Sep 2023 13:53:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7537210E2D4; Mon, 18 Sep 2023 13:53:06 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7C14010E190; Mon, 18 Sep 2023 13:53:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045182; x=1726581182; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cthm1tBJCPYtwDo3WuAmuyxQhQxFVxdwHpDlz5ogKBE=; b=XAHWIBXcTG+K2hPeGhHQj+Loz9ZN1C+fx4T1Uouy2z7G+KNWNNYCsTDm qHVZrYgGHLpiae02tyEvxcSn59KKWf8/yeB9zuJQhSgm2SwbO0H3JjMIt 99n7ZHztbp/GzHN5vGkRWqPLJtkzOsI9DILGLcFK+UEKuM48TP/LWZtTa I+2r+fbZ6gbVhzQRFmPU9EHqYnChD//RYSuBNw6yDZVQhjL1lKQogv9W9 psYfVnt0DSObdpwmOZblMYIDrwQJnV3hL7J1dfZDpMANYavPvjYfUzvjA G0lYYaEnCtRQ8eZs9iDNUHlJmpHIvZRjr6hYdbtF7TXOp0BaCg4ZBuotb A==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969747" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969747" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:53:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030597" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030597" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:53:00 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:06 +0200 Message-ID: <20230918134249.31645-35-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- lib/igt_kmod.c | 23 ++++++++++++++++++++--- tests/drm_mm.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index 7fa5b4aa80..f6e0ab07ce 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -978,7 +978,27 @@ void igt_kunit(const char *module_name, const char *name, const char *opts) struct igt_ktest tst = { .kmsg = -1, }; + /* + * 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_skip_on(igt_ktest_init(&tst, module_name)); igt_skip_on(igt_ktest_begin(&tst)); } @@ -990,9 +1010,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 Mon Sep 18 13:43:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 13389680 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 667A6CD37B0 for ; Mon, 18 Sep 2023 13:53:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CC84310E286; Mon, 18 Sep 2023 13:53:09 +0000 (UTC) Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id E8C2D10E2C5; Mon, 18 Sep 2023 13:53:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695045185; x=1726581185; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Vt+qFfpL+cuWq9+pc5nzMWSke2+CYAEajidbWL5HH1g=; b=X4UBd9wqe2d0t5ax2Z2heiRa0VpmZGSahrKPTib6v5Ub75+kgqJ4Sfep oZA9fIvYueMR/8BBJLT7fGqFMUtm7mltZR72ndwQfV42KDk0wohSvTTVM 6RKj05tuEcI72od1u8pcc4XLWWndPhNpWrqQ2rK/akKnhhJP1ANSFIK96 WY1r0rQhUqDo9tEc+1YZSJYhJjvuWToOKXGP3fcZter7YcKu4ZPQw9Tu7 SAHlurGQ41N7IaolCGBdzgNzDGwP2pIZY0TrMaJvBNrvo6JfoK4fizwET 9GsmALYop/Lt8HpmW09v1YtS+cF6OT7sYTCXXyO6mYFpf124LL9uzpTis Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="376969758" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="376969758" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:53:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10837"; a="749030606" X-IronPort-AV: E=Sophos;i="6.02,156,1688454000"; d="scan'208";a="749030606" Received: from jkrzyszt-mobl2.ger.corp.intel.com ([10.213.18.199]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2023 06:53:02 -0700 From: Janusz Krzysztofik To: igt-dev@lists.freedesktop.org Date: Mon, 18 Sep 2023 15:43:07 +0200 Message-ID: <20230918134249.31645-36-janusz.krzysztofik@linux.intel.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> References: <20230918134249.31645-19-janusz.krzysztofik@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t v3 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 Reviewed-by: Mauro Carvalho Chehab --- 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 f6e0ab07ce..05c837031c 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -863,7 +863,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 = { pthread_self(), tst->kmod, opts, 0, PTHREAD_MUTEX_INITIALIZER, }; @@ -902,7 +903,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); @@ -1011,7 +1016,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_fixture igt_ktest_end(&tst);