At present the kselftest header can't be used with nolibc since it makes use of vprintf() which is not available in nolibc. Fortunately nolibc has a vfprintf() so we can just wrap that in order to allow kselftests to be built with nolibc and still use the standard kselftest headers with a small change to prevent the inclusion of the standard libc headers. This allows us to avoid open coding of KTAP output for selftests that need to use nolibc in order to test interfaces that are controlled by libc, we've got several open coded examples of this in the tree already.
As an example of using this the existing za-fork test is converted to use kselftest.h. The changes to kselftest and nolibc don't have any interaction until they are used by a test so could be merged separately if desired.
Signed-off-by: Mark Brown broonie@kernel.org --- Changes in v2: - Turns out nolibc has a vfprintf() already which we can use so do that. - Link to v1: https://lore.kernel.org/r/20230405-kselftest-nolibc-v1-0-63fbcd70b202@kernel...
--- Mark Brown (3): tools/nolibc/stdio: Implement vprintf() kselftest: Support nolibc kselftest/arm64: Convert za-fork to use kselftest.h
tools/include/nolibc/stdio.h | 6 ++ tools/testing/selftests/arm64/fp/Makefile | 2 +- tools/testing/selftests/arm64/fp/za-fork.c | 88 ++++++------------------------ tools/testing/selftests/kselftest.h | 2 + 4 files changed, 25 insertions(+), 73 deletions(-) --- base-commit: e8d018dd0257f744ca50a729e3d042cf2ec9da65 change-id: 20230405-kselftest-nolibc-cb2ce0446d09
Best regards,
vprintf() is equivalent to vfprintf() to stdout so implement it as a simple wrapper for the existing vfprintf(), allowing us to build kselftest.h.
Suggested-by: Willy Tarreau w@1wt.eu Signed-off-by: Mark Brown broonie@kernel.org --- tools/include/nolibc/stdio.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 96ac8afc5aee..6cbbb52836a0 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args) return written; }
+static __attribute__((unused)) +int vprintf(const char *fmt, va_list args) +{ + return vfprintf(stdout, fmt, args); +} + static __attribute__((unused, format(printf, 2, 3))) int fprintf(FILE *stream, const char *fmt, ...) {
On Thu, Apr 06, 2023 at 05:19:10PM +0100, Mark Brown wrote:
vprintf() is equivalent to vfprintf() to stdout so implement it as a simple wrapper for the existing vfprintf(), allowing us to build kselftest.h.
Suggested-by: Willy Tarreau w@1wt.eu Signed-off-by: Mark Brown broonie@kernel.org
tools/include/nolibc/stdio.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 96ac8afc5aee..6cbbb52836a0 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args) return written; } +static __attribute__((unused)) +int vprintf(const char *fmt, va_list args) +{
- return vfprintf(stdout, fmt, args);
+}
static __attribute__((unused, format(printf, 2, 3))) int fprintf(FILE *stream, const char *fmt, ...) {
Perfect, thank you Mark, I'm glad that it simplified the rest of your series.
Acked-by: Willy Tarreau w@1wt.eu
Paul, feel free to directly queue this one for 6.5. If you prefer I can as well queue it on my side and send it later, it's just that I have exactly zero extra value on top of this one ;-)
Thanks, Willy
On Thu, Apr 06, 2023 at 08:26:09PM +0200, Willy Tarreau wrote:
On Thu, Apr 06, 2023 at 05:19:10PM +0100, Mark Brown wrote:
vprintf() is equivalent to vfprintf() to stdout so implement it as a simple wrapper for the existing vfprintf(), allowing us to build kselftest.h.
Suggested-by: Willy Tarreau w@1wt.eu Signed-off-by: Mark Brown broonie@kernel.org
tools/include/nolibc/stdio.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 96ac8afc5aee..6cbbb52836a0 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args) return written; } +static __attribute__((unused)) +int vprintf(const char *fmt, va_list args) +{
- return vfprintf(stdout, fmt, args);
+}
static __attribute__((unused, format(printf, 2, 3))) int fprintf(FILE *stream, const char *fmt, ...) {
Perfect, thank you Mark, I'm glad that it simplified the rest of your series.
Acked-by: Willy Tarreau w@1wt.eu
Paul, feel free to directly queue this one for 6.5. If you prefer I can as well queue it on my side and send it later, it's just that I have exactly zero extra value on top of this one ;-)
Alternatively, if it would be more convenient for Mark to send this up via kselftest:
Acked-by: Paul E. McKenney paulmck@kernel.org
It currently merges cleanly with the -rcu tree's dev branch, so this should not be a problem.
Either way, please let me know, Mark!
Thanx, Paul
On 4/6/23 12:43, Paul E. McKenney wrote:
On Thu, Apr 06, 2023 at 08:26:09PM +0200, Willy Tarreau wrote:
On Thu, Apr 06, 2023 at 05:19:10PM +0100, Mark Brown wrote:
vprintf() is equivalent to vfprintf() to stdout so implement it as a simple wrapper for the existing vfprintf(), allowing us to build kselftest.h.
Suggested-by: Willy Tarreau w@1wt.eu Signed-off-by: Mark Brown broonie@kernel.org
tools/include/nolibc/stdio.h | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 96ac8afc5aee..6cbbb52836a0 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -273,6 +273,12 @@ int vfprintf(FILE *stream, const char *fmt, va_list args) return written; } +static __attribute__((unused)) +int vprintf(const char *fmt, va_list args) +{
- return vfprintf(stdout, fmt, args);
+}
- static __attribute__((unused, format(printf, 2, 3))) int fprintf(FILE *stream, const char *fmt, ...) {
Perfect, thank you Mark, I'm glad that it simplified the rest of your series.
Acked-by: Willy Tarreau w@1wt.eu
Paul, feel free to directly queue this one for 6.5. If you prefer I can as well queue it on my side and send it later, it's just that I have exactly zero extra value on top of this one ;-)
Alternatively, if it would be more convenient for Mark to send this up via kselftest:
Acked-by: Paul E. McKenney paulmck@kernel.org
It currently merges cleanly with the -rcu tree's dev branch, so this should not be a problem.
Either way, please let me know, Mark!
I can take these through kselftest or can go through arm64
Acked-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On Mon, Apr 10, 2023 at 12:30:04PM -0600, Shuah Khan wrote:
On 4/6/23 12:43, Paul E. McKenney wrote:
Alternatively, if it would be more convenient for Mark to send this up via kselftest:
Acked-by: Paul E. McKenney paulmck@kernel.org
It currently merges cleanly with the -rcu tree's dev branch, so this should not be a problem.
Either way, please let me know, Mark!
I can take these through kselftest or can go through arm64
Acked-by: Shuah Khan skhan@linuxfoundation.org
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
On Tue, Apr 11, 2023 at 03:31:10PM +0100, Mark Brown wrote:
On Mon, Apr 10, 2023 at 12:30:04PM -0600, Shuah Khan wrote:
On 4/6/23 12:43, Paul E. McKenney wrote:
Alternatively, if it would be more convenient for Mark to send this up via kselftest:
Acked-by: Paul E. McKenney paulmck@kernel.org
It currently merges cleanly with the -rcu tree's dev branch, so this should not be a problem.
Either way, please let me know, Mark!
I can take these through kselftest or can go through arm64
Acked-by: Shuah Khan skhan@linuxfoundation.org
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
Fine by me, as long as it doesn't conflict with any other arm64 selftest changes you hope to land for 6.4.
Will
On Tue, Apr 11, 2023 at 04:03:21PM +0100, Will Deacon wrote:
On Tue, Apr 11, 2023 at 03:31:10PM +0100, Mark Brown wrote:
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
Fine by me, as long as it doesn't conflict with any other arm64 selftest changes you hope to land for 6.4.
That shouldn't be an issue.
On Tue, Apr 11, 2023 at 04:13:11PM +0100, Mark Brown wrote:
On Tue, Apr 11, 2023 at 04:03:21PM +0100, Will Deacon wrote:
On Tue, Apr 11, 2023 at 03:31:10PM +0100, Mark Brown wrote:
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
Fine by me, as long as it doesn't conflict with any other arm64 selftest changes you hope to land for 6.4.
That shouldn't be an issue.
Shuah, looks to me like this one is yours in kselftest, then. ;-)
Thanx, Paul
On 4/11/23 10:44, Paul E. McKenney wrote:
On Tue, Apr 11, 2023 at 04:13:11PM +0100, Mark Brown wrote:
On Tue, Apr 11, 2023 at 04:03:21PM +0100, Will Deacon wrote:
On Tue, Apr 11, 2023 at 03:31:10PM +0100, Mark Brown wrote:
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
Fine by me, as long as it doesn't conflict with any other arm64 selftest changes you hope to land for 6.4.
That shouldn't be an issue.
Shuah, looks to me like this one is yours in kselftest, then. ;-)
Thanx, Paul
I will pick these up for Linux 6.4 thanks, -- Shuah
On Tue, Apr 11, 2023 at 12:54:29PM -0600, Shuah Khan wrote:
On 4/11/23 10:44, Paul E. McKenney wrote:
On Tue, Apr 11, 2023 at 04:13:11PM +0100, Mark Brown wrote:
On Tue, Apr 11, 2023 at 04:03:21PM +0100, Will Deacon wrote:
On Tue, Apr 11, 2023 at 03:31:10PM +0100, Mark Brown wrote:
It seems like more of a kselftest change than anything else so probably makes sense for it to go that way? The example user isn't really even needed.
Fine by me, as long as it doesn't conflict with any other arm64 selftest changes you hope to land for 6.4.
That shouldn't be an issue.
Shuah, looks to me like this one is yours in kselftest, then. ;-)
Thanx, Paul
I will pick these up for Linux 6.4
Cheers, Shuah!
Will
Rather than providing headers for inclusion which replace any offered by the system nolibc is provided in the form of a header which should be added to the build via the compiler command line. In order to build with nolibc we need to not include the standard C headers, especially not stdio.h where the definitions of stdout, stdin and stderr will actively conflict with nolibc.
Add an include guard which suppresses the inclusion of the standard headers when building with nolibc, allowing us to build tests using the nolibc headers. This allows us to avoid open coding of KTAP output for selftests that need to use nolibc in order to test interfaces that are controlled by libc.
Signed-off-by: Mark Brown broonie@kernel.org --- tools/testing/selftests/kselftest.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index 33a0dbd26bd3..829be379545a 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -43,11 +43,13 @@ #ifndef __KSELFTEST_H #define __KSELFTEST_H
+#ifndef NOLIBC #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <stdarg.h> #include <stdio.h> +#endif
#ifndef ARRAY_SIZE #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
Now that kselftest.h can be used with nolibc convert the za-fork test to use it. We do still have to open code ksft_print_msg() but that's not the end of the world. Some of the advantage comes from using printf() which we could have been using already.
This does change the output when tests are skipped, bringing it in line with the standard kselftest output by removing the test name - we move from
ok 0 skipped
to
ok 1 # SKIP fork_test
The old output was not following KTAP format for skips, and the numbering was not standard or consistent with the reported plan.
Signed-off-by: Mark Brown broonie@kernel.org --- tools/testing/selftests/arm64/fp/Makefile | 2 +- tools/testing/selftests/arm64/fp/za-fork.c | 88 ++++++------------------------ 2 files changed, 17 insertions(+), 73 deletions(-)
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile index 48f56c86ad45..b413b0af07f9 100644 --- a/tools/testing/selftests/arm64/fp/Makefile +++ b/tools/testing/selftests/arm64/fp/Makefile @@ -38,7 +38,7 @@ $(OUTPUT)/vec-syscfg: vec-syscfg.c $(OUTPUT)/rdvl.o $(OUTPUT)/vlset: vlset.c $(OUTPUT)/za-fork: za-fork.c $(OUTPUT)/za-fork-asm.o $(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ - -include ../../../../include/nolibc/nolibc.h \ + -include ../../../../include/nolibc/nolibc.h -I../..\ -static -ffreestanding -Wall $^ -o $@ $(OUTPUT)/za-ptrace: za-ptrace.c $(OUTPUT)/za-test: za-test.S $(OUTPUT)/asm-utils.o diff --git a/tools/testing/selftests/arm64/fp/za-fork.c b/tools/testing/selftests/arm64/fp/za-fork.c index ff475c649e96..b86cb1049497 100644 --- a/tools/testing/selftests/arm64/fp/za-fork.c +++ b/tools/testing/selftests/arm64/fp/za-fork.c @@ -9,42 +9,9 @@ #include <linux/sched.h> #include <linux/wait.h>
-#define EXPECTED_TESTS 1 - -static void putstr(const char *str) -{ - write(1, str, strlen(str)); -} - -static void putnum(unsigned int num) -{ - char c; - - if (num / 10) - putnum(num / 10); - - c = '0' + (num % 10); - write(1, &c, 1); -} +#include "kselftest.h"
-static int tests_run; -static int tests_passed; -static int tests_failed; -static int tests_skipped; - -static void print_summary(void) -{ - if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS) - putstr("# UNEXPECTED TEST COUNT: "); - - putstr("# Totals: pass:"); - putnum(tests_passed); - putstr(" fail:"); - putnum(tests_failed); - putstr(" xfail:0 xpass:0 skip:"); - putnum(tests_skipped); - putstr(" error:0\n"); -} +#define EXPECTED_TESTS 1
int fork_test(void); int verify_fork(void); @@ -63,22 +30,21 @@ int fork_test_c(void) if (newpid == 0) { /* In child */ if (!verify_fork()) { - putstr("# ZA state invalid in child\n"); + ksft_print_msg("ZA state invalid in child\n"); exit(0); } else { exit(1); } } if (newpid < 0) { - putstr("# fork() failed: -"); - putnum(-newpid); - putstr("\n"); + ksft_print_msg("fork() failed: %d\n", newpid); + return 0; }
parent_result = verify_fork(); if (!parent_result) - putstr("# ZA state invalid in parent\n"); + ksft_print_msg("ZA state invalid in parent\n");
for (;;) { waiting = waitpid(newpid, &child_status, 0); @@ -86,18 +52,16 @@ int fork_test_c(void) if (waiting < 0) { if (errno == EINTR) continue; - putstr("# waitpid() failed: "); - putnum(errno); - putstr("\n"); + ksft_print_msg("waitpid() failed: %d\n", errno); return 0; } if (waiting != newpid) { - putstr("# waitpid() returned wrong PID\n"); + ksft_print_msg("waitpid() returned wrong PID\n"); return 0; }
if (!WIFEXITED(child_status)) { - putstr("# child did not exit\n"); + ksft_print_msg("child did not exit\n"); return 0; }
@@ -105,29 +69,14 @@ int fork_test_c(void) } }
-#define run_test(name) \ - if (name()) { \ - tests_passed++; \ - } else { \ - tests_failed++; \ - putstr("not "); \ - } \ - putstr("ok "); \ - putnum(++tests_run); \ - putstr(" " #name "\n"); - int main(int argc, char **argv) { int ret, i;
- putstr("TAP version 13\n"); - putstr("1.."); - putnum(EXPECTED_TESTS); - putstr("\n"); + ksft_print_header(); + ksft_set_plan(EXPECTED_TESTS);
- putstr("# PID: "); - putnum(getpid()); - putstr("\n"); + ksft_print_msg("PID: %d\n", getpid());
/* * This test is run with nolibc which doesn't support hwcap and @@ -136,21 +85,16 @@ int main(int argc, char **argv) */ ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0); if (ret >= 0) { - run_test(fork_test); + ksft_test_result(fork_test(), "fork_test");
} else { - putstr("# SME support not present\n"); - + ksft_print_msg("SME not supported\n"); for (i = 0; i < EXPECTED_TESTS; i++) { - putstr("ok "); - putnum(i); - putstr(" skipped\n"); + ksft_test_result_skip("fork_test\n"); } - - tests_skipped += EXPECTED_TESTS; }
- print_summary(); + ksft_finished();
return 0; }
linux-kselftest-mirror@lists.linaro.org