From 03438212d0b0ea2cf201e921c9056f683c624ffb Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:39:57 -0700 Subject: selftests/timers: Cleanup Makefile to make it easier to add future tests Try to streamline the makefile so its easier to add timer/timekeeping tests. Also adds support for the CROSS_COMPILE variable. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index eb2859f..e65c543 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -1,8 +1,13 @@ -all: - gcc posix_timers.c -o posix_timers -lrt +CC = $(CROSS_COMPILE)gcc +BUILD_FLAGS = -DKTEST +CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) +LDFLAGS += -lrt -lpthread +bins = posix_timers + +all: ${bins} run_tests: all ./posix_timers clean: - rm -f ./posix_timers + rm -f ${bins} -- cgit v1.1 From 2430ec652dd67243484c90fe34a4433622fc2a30 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:39:58 -0700 Subject: selftests/timers: Quiet warning due to lack of return check on brk The posix_timers.c test has a loop that tries to keep it in kernel space, repeatedly calling brk(). However, it doesn't check the return value, which causes warnings. This patch adds a err value which captures the return value and modifies the test so it will quit if a failure occurs. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/posix_timers.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index f87d970..5a246a0 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -35,10 +35,11 @@ static void user_loop(void) static void kernel_loop(void) { void *addr = sbrk(0); + int err = 0; - while (!done) { - brk(addr + 4096); - brk(addr); + while (!done && !err) { + err = brk(addr + 4096); + err |= brk(addr); } } @@ -190,8 +191,6 @@ static int check_timer_create(int which) int main(int argc, char **argv) { - int err; - printf("Testing posix timers. False negative may happen on CPU execution \n"); printf("based timers if other threads run on the CPU...\n"); -- cgit v1.1 From 689f32fbb81356efac9fac99c740c4c232634c41 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:39:59 -0700 Subject: selftests/timers: Add nanosleep test from timetest suite Add my basic nanosleep test from my timetest suite. This test validates that nanosleep doesn't return early against a number of clockids. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/nanosleep.c | 174 +++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/nanosleep.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index e65c543..9409423 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,12 +2,13 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers +bins = posix_timers nanosleep all: ${bins} run_tests: all ./posix_timers + ./nanosleep clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/nanosleep.c b/tools/testing/selftests/timers/nanosleep.c new file mode 100644 index 0000000..8a3c29d --- /dev/null +++ b/tools/testing/selftests/timers/nanosleep.c @@ -0,0 +1,174 @@ +/* Make sure timers don't return early + * by: john stultz (johnstul@us.ibm.com) + * John Stultz (john.stultz@linaro.org) + * (C) Copyright IBM 2012 + * (C) Copyright Linaro 2013 2015 + * Licensed under the GPLv2 + * + * To build: + * $ gcc nanosleep.c -o nanosleep -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000ULL + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 +#define CLOCK_REALTIME_COARSE 5 +#define CLOCK_MONOTONIC_COARSE 6 +#define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 +#define CLOCK_HWSPECIFIC 10 +#define CLOCK_TAI 11 +#define NR_CLOCKIDS 12 + +#define UNSUPPORTED 0xf00f + +char *clockstring(int clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + }; + return "UNKNOWN_CLOCKID"; +} + +/* returns 1 if a <= b, 0 otherwise */ +static inline int in_order(struct timespec a, struct timespec b) +{ + if (a.tv_sec < b.tv_sec) + return 1; + if (a.tv_sec > b.tv_sec) + return 0; + if (a.tv_nsec > b.tv_nsec) + return 0; + return 1; +} + +struct timespec timespec_add(struct timespec ts, unsigned long long ns) +{ + ts.tv_nsec += ns; + while (ts.tv_nsec >= NSEC_PER_SEC) { + ts.tv_nsec -= NSEC_PER_SEC; + ts.tv_sec++; + } + return ts; +} + +int nanosleep_test(int clockid, long long ns) +{ + struct timespec now, target, rel; + + /* First check abs time */ + if (clock_gettime(clockid, &now)) + return UNSUPPORTED; + target = timespec_add(now, ns); + + if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL)) + return UNSUPPORTED; + clock_gettime(clockid, &now); + + if (!in_order(target, now)) + return -1; + + /* Second check reltime */ + clock_gettime(clockid, &now); + rel.tv_sec = 0; + rel.tv_nsec = 0; + rel = timespec_add(rel, ns); + target = timespec_add(now, ns); + clock_nanosleep(clockid, 0, &rel, NULL); + clock_gettime(clockid, &now); + + if (!in_order(target, now)) + return -1; + return 0; +} + +int main(int argc, char **argv) +{ + long long length; + int clockid, ret; + + for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { + + /* Skip cputime clockids since nanosleep won't increment cputime */ + if (clockid == CLOCK_PROCESS_CPUTIME_ID || + clockid == CLOCK_THREAD_CPUTIME_ID || + clockid == CLOCK_HWSPECIFIC) + continue; + + printf("Nanosleep %-31s ", clockstring(clockid)); + + length = 10; + while (length <= (NSEC_PER_SEC * 10)) { + ret = nanosleep_test(clockid, length); + if (ret == UNSUPPORTED) { + printf("[UNSUPPORTED]\n"); + goto next; + } + if (ret < 0) { + printf("[FAILED]\n"); + return ksft_exit_fail(); + } + length *= 100; + } + printf("[OK]\n"); +next: + ret = 0; + } + return ksft_exit_pass(); +} -- cgit v1.1 From ed3fe34a2a4e0c9f184a178c48acf20c7acf244e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:00 -0700 Subject: selftests/timers: Add inconsistency-check test from timetests This adds my inconsistency-test from my timetests suite, which checks for (single threaded) time inconsistencies across the various clockids. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 4 +- .../testing/selftests/timers/inconsistency-check.c | 204 +++++++++++++++++++++ 2 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/timers/inconsistency-check.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 9409423..fcb7c2f 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,13 +2,13 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers nanosleep +bins = posix_timers nanosleep inconsistency-check all: ${bins} run_tests: all ./posix_timers ./nanosleep - + ./inconsistency-check clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c new file mode 100644 index 0000000..578e423 --- /dev/null +++ b/tools/testing/selftests/timers/inconsistency-check.c @@ -0,0 +1,204 @@ +/* Time inconsistency check test + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2003, 2004, 2005, 2012 + * (C) Copyright Linaro Limited 2015 + * Licensed under the GPLv2 + * + * To build: + * $ gcc inconsistency-check.c -o inconsistency-check -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define CALLS_PER_LOOP 64 +#define NSEC_PER_SEC 1000000000ULL + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 +#define CLOCK_REALTIME_COARSE 5 +#define CLOCK_MONOTONIC_COARSE 6 +#define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 +#define CLOCK_HWSPECIFIC 10 +#define CLOCK_TAI 11 +#define NR_CLOCKIDS 12 + +char *clockstring(int clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + }; + return "UNKNOWN_CLOCKID"; +} + +/* returns 1 if a <= b, 0 otherwise */ +static inline int in_order(struct timespec a, struct timespec b) +{ + /* use unsigned to avoid false positives on 2038 rollover */ + if ((unsigned long)a.tv_sec < (unsigned long)b.tv_sec) + return 1; + if ((unsigned long)a.tv_sec > (unsigned long)b.tv_sec) + return 0; + if (a.tv_nsec > b.tv_nsec) + return 0; + return 1; +} + + + +int consistency_test(int clock_type, unsigned long seconds) +{ + struct timespec list[CALLS_PER_LOOP]; + int i, inconsistent; + long now, then; + time_t t; + char *start_str; + + clock_gettime(clock_type, &list[0]); + now = then = list[0].tv_sec; + + /* timestamp start of test */ + t = time(0); + start_str = ctime(&t); + + while (seconds == -1 || now - then < seconds) { + inconsistent = 0; + + /* Fill list */ + for (i = 0; i < CALLS_PER_LOOP; i++) + clock_gettime(clock_type, &list[i]); + + /* Check for inconsistencies */ + for (i = 0; i < CALLS_PER_LOOP - 1; i++) + if (!in_order(list[i], list[i+1])) + inconsistent = i; + + /* display inconsistency */ + if (inconsistent) { + unsigned long long delta; + + printf("\%s\n", start_str); + for (i = 0; i < CALLS_PER_LOOP; i++) { + if (i == inconsistent) + printf("--------------------\n"); + printf("%lu:%lu\n", list[i].tv_sec, + list[i].tv_nsec); + if (i == inconsistent + 1) + printf("--------------------\n"); + } + delta = list[inconsistent].tv_sec * NSEC_PER_SEC; + delta += list[inconsistent].tv_nsec; + delta -= list[inconsistent+1].tv_sec * NSEC_PER_SEC; + delta -= list[inconsistent+1].tv_nsec; + printf("Delta: %llu ns\n", delta); + fflush(0); + /* timestamp inconsistency*/ + t = time(0); + printf("%s\n", ctime(&t)); + printf("[FAILED]\n"); + return -1; + } + now = list[0].tv_sec; + } + printf("[OK]\n"); + return 0; +} + + +int main(int argc, char *argv[]) +{ + int clockid, opt; + int userclock = CLOCK_REALTIME; + int maxclocks = NR_CLOCKIDS; + int runtime = 30; + struct timespec ts; + + /* Process arguments */ + while ((opt = getopt(argc, argv, "t:c:")) != -1) { + switch (opt) { + case 't': + runtime = atoi(optarg); + break; + case 'c': + userclock = atoi(optarg); + maxclocks = userclock + 1; + break; + default: + printf("Usage: %s [-t ] [-c ]\n", argv[0]); + printf(" -t: Number of seconds to run\n"); + printf(" -c: clockid to use (default, all clockids)\n"); + exit(-1); + } + } + + setbuf(stdout, NULL); + + for (clockid = userclock; clockid < maxclocks; clockid++) { + + if (clockid == CLOCK_HWSPECIFIC) + continue; + + if (!clock_gettime(clockid, &ts)) { + printf("Consistent %-30s ", clockstring(clockid)); + if (consistency_test(clockid, runtime)) + return ksft_exit_fail(); + } + } + return ksft_exit_pass(); +} -- cgit v1.1 From c5fffcb2bd4e2fdc37875fc4368db49ac927d6df Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:01 -0700 Subject: selftests/timers: Add nsleep-lat test from timetest suite Adds my nanosleep latency test from the timetest suite. This checks to make sure we don't see "unreasonable" latencies (> 40ms) when calling nanosleep. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/nsleep-lat.c | 190 ++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/nsleep-lat.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index fcb7c2f..dae9ee7 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,13 +2,14 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers nanosleep inconsistency-check +bins = posix_timers nanosleep inconsistency-check nsleep-lat all: ${bins} run_tests: all ./posix_timers ./nanosleep + ./nsleep-lat ./inconsistency-check clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/nsleep-lat.c b/tools/testing/selftests/timers/nsleep-lat.c new file mode 100644 index 0000000..2d7898f --- /dev/null +++ b/tools/testing/selftests/timers/nsleep-lat.c @@ -0,0 +1,190 @@ +/* Measure nanosleep timer latency + * by: john stultz (john.stultz@linaro.org) + * (C) Copyright Linaro 2013 + * Licensed under the GPLv2 + * + * To build: + * $ gcc nsleep-lat.c -o nsleep-lat -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000ULL + +#define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ + + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 +#define CLOCK_REALTIME_COARSE 5 +#define CLOCK_MONOTONIC_COARSE 6 +#define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 +#define CLOCK_HWSPECIFIC 10 +#define CLOCK_TAI 11 +#define NR_CLOCKIDS 12 + +#define UNSUPPORTED 0xf00f + +char *clockstring(int clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + }; + return "UNKNOWN_CLOCKID"; +} + +struct timespec timespec_add(struct timespec ts, unsigned long long ns) +{ + ts.tv_nsec += ns; + while (ts.tv_nsec >= NSEC_PER_SEC) { + ts.tv_nsec -= NSEC_PER_SEC; + ts.tv_sec++; + } + return ts; +} + + +long long timespec_sub(struct timespec a, struct timespec b) +{ + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; + + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; + return ret; +} + +int nanosleep_lat_test(int clockid, long long ns) +{ + struct timespec start, end, target; + long long latency = 0; + int i, count; + + target.tv_sec = ns/NSEC_PER_SEC; + target.tv_nsec = ns%NSEC_PER_SEC; + + if (clock_gettime(clockid, &start)) + return UNSUPPORTED; + if (clock_nanosleep(clockid, 0, &target, NULL)) + return UNSUPPORTED; + + count = 10; + + /* First check relative latency */ + clock_gettime(clockid, &start); + for (i = 0; i < count; i++) + clock_nanosleep(clockid, 0, &target, NULL); + clock_gettime(clockid, &end); + + if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) { + printf("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns); + return -1; + } + + /* Next check absolute latency */ + for (i = 0; i < count; i++) { + clock_gettime(clockid, &start); + target = timespec_add(start, ns); + clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL); + clock_gettime(clockid, &end); + latency += timespec_sub(target, end); + } + + if (latency/count > UNRESONABLE_LATENCY) { + printf("Large abs latency: %lld ns :", latency/count); + return -1; + } + + return 0; +} + + + +int main(int argc, char **argv) +{ + long long length; + int clockid, ret; + + for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { + + /* Skip cputime clockids since nanosleep won't increment cputime */ + if (clockid == CLOCK_PROCESS_CPUTIME_ID || + clockid == CLOCK_THREAD_CPUTIME_ID || + clockid == CLOCK_HWSPECIFIC) + continue; + + printf("nsleep latency %-26s ", clockstring(clockid)); + + length = 10; + while (length <= (NSEC_PER_SEC * 10)) { + ret = nanosleep_lat_test(clockid, length); + if (ret) + break; + length *= 100; + + } + + if (ret == UNSUPPORTED) { + printf("[UNSUPPORTED]\n"); + continue; + } + if (ret < 0) { + printf("[FAILED]\n"); + return ksft_exit_fail(); + } + printf("[OK]\n"); + } + return ksft_exit_pass(); +} -- cgit v1.1 From 51f91cbdf5450b773eb221a2dfd141a92413370e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:02 -0700 Subject: selftests/timers: Add clock skew estimation test from timetest suite This adds my clock skew estimation test from the timetest suite. It measures the drift between CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW and compares it with the current frequency value from adjtimex. It sometimes can trigger false failures when ntpd isn't in a steady state, but its a useful too when doing adjtimex testing. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/raw_skew.c | 154 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/raw_skew.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index dae9ee7..088a791 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,7 +2,7 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers nanosleep inconsistency-check nsleep-lat +bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew all: ${bins} @@ -11,5 +11,6 @@ run_tests: all ./nanosleep ./nsleep-lat ./inconsistency-check + ./raw_skew clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c new file mode 100644 index 0000000..30906bf --- /dev/null +++ b/tools/testing/selftests/timers/raw_skew.c @@ -0,0 +1,154 @@ +/* CLOCK_MONOTONIC vs CLOCK_MONOTONIC_RAW skew test + * by: john stultz (johnstul@us.ibm.com) + * John Stultz + * (C) Copyright IBM 2012 + * (C) Copyright Linaro Limited 2015 + * Licensed under the GPLv2 + * + * To build: + * $ gcc raw_skew.c -o raw_skew -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + + +#define CLOCK_MONOTONIC_RAW 4 +#define NSEC_PER_SEC 1000000000LL + +#define shift_right(x, s) ({ \ + __typeof__(x) __x = (x); \ + __typeof__(s) __s = (s); \ + __x < 0 ? -(-__x >> __s) : __x >> __s; \ +}) + +long long llabs(long long val) +{ + if (val < 0) + val = -val; + return val; +} + +unsigned long long ts_to_nsec(struct timespec ts) +{ + return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; +} + +struct timespec nsec_to_ts(long long ns) +{ + struct timespec ts; + + ts.tv_sec = ns/NSEC_PER_SEC; + ts.tv_nsec = ns%NSEC_PER_SEC; + return ts; +} + +long long diff_timespec(struct timespec start, struct timespec end) +{ + long long start_ns, end_ns; + + start_ns = ts_to_nsec(start); + end_ns = ts_to_nsec(end); + return end_ns - start_ns; +} + +void get_monotonic_and_raw(struct timespec *mon, struct timespec *raw) +{ + struct timespec start, mid, end; + long long diff = 0, tmp; + int i; + + for (i = 0; i < 3; i++) { + long long newdiff; + + clock_gettime(CLOCK_MONOTONIC, &start); + clock_gettime(CLOCK_MONOTONIC_RAW, &mid); + clock_gettime(CLOCK_MONOTONIC, &end); + + newdiff = diff_timespec(start, end); + if (diff == 0 || newdiff < diff) { + diff = newdiff; + *raw = mid; + tmp = (ts_to_nsec(start) + ts_to_nsec(end))/2; + *mon = nsec_to_ts(tmp); + } + } +} + +int main(int argv, char **argc) +{ + struct timespec mon, raw, start, end; + long long delta1, delta2, interval, eppm, ppm; + struct timex tx1, tx2; + + setbuf(stdout, NULL); + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &raw)) { + printf("ERR: NO CLOCK_MONOTONIC_RAW\n"); + return -1; + } + + tx1.modes = 0; + adjtimex(&tx1); + get_monotonic_and_raw(&mon, &raw); + start = mon; + delta1 = diff_timespec(mon, raw); + + if (tx1.offset) + printf("WARNING: ADJ_OFFSET in progress, this will cause inaccurate results\n"); + + printf("Estimating clock drift: "); + sleep(120); + + get_monotonic_and_raw(&mon, &raw); + end = mon; + tx2.modes = 0; + adjtimex(&tx2); + delta2 = diff_timespec(mon, raw); + + interval = diff_timespec(start, end); + + /* calculate measured ppm between MONOTONIC and MONOTONIC_RAW */ + eppm = ((delta2-delta1)*NSEC_PER_SEC)/interval; + eppm = -eppm; + printf("%lld.%i(est)", eppm/1000, abs((int)(eppm%1000))); + + /* Avg the two actual freq samples adjtimex gave us */ + ppm = (tx1.freq + tx2.freq) * 1000 / 2; + ppm = (long long)tx1.freq * 1000; + ppm = shift_right(ppm, 16); + printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); + + if (llabs(eppm - ppm) > 1000) { + printf(" [FAILED]\n"); + return ksft_exit_fail(); + } + printf(" [OK]\n"); + return ksft_exit_pass(); +} -- cgit v1.1 From 4e40d0a22e728102bfea9543d827ee72206eecbb Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:03 -0700 Subject: selftests/timers: Add set-timer-lat test from timetest suite Add my set-timer-lat test from the timetest suite. This test checks the latency from set_timer and reports if any are unreasonable (>40ms). Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 5 +- tools/testing/selftests/timers/set-timer-lat.c | 209 +++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/set-timer-lat.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 088a791..f69bdce 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,7 +2,8 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew +bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ + set-timer-lat all: ${bins} @@ -10,7 +11,9 @@ run_tests: all ./posix_timers ./nanosleep ./nsleep-lat + ./set-timer-lat ./inconsistency-check ./raw_skew + clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c new file mode 100644 index 0000000..3ea2eff --- /dev/null +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -0,0 +1,209 @@ +/* set_timer latency test + * John Stultz (john.stultz@linaro.org) + * (C) Copyright Linaro 2014 + * Licensed under the GPLv2 + * + * This test makes sure the set_timer api is correct + * + * To build: + * $ gcc set-timer-lat.c -o set-timer-lat -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 +#define CLOCK_REALTIME_COARSE 5 +#define CLOCK_MONOTONIC_COARSE 6 +#define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 +#define CLOCK_HWSPECIFIC 10 +#define CLOCK_TAI 11 +#define NR_CLOCKIDS 12 + + +#define NSEC_PER_SEC 1000000000ULL +#define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ + +#define TIMER_SECS 3 +int alarmcount; +int clock_id; +struct timespec start_time; +long long max_latency_ns; + +char *clockstring(int clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + }; + return "UNKNOWN_CLOCKID"; +} + + +long long timespec_sub(struct timespec a, struct timespec b) +{ + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; + + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; + return ret; +} + + +void sigalarm(int signo) +{ + long long delta_ns; + struct timespec ts; + + clock_gettime(clock_id, &ts); + alarmcount++; + + delta_ns = timespec_sub(start_time, ts); + delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; + + if (delta_ns < 0) + printf("%s timer fired early: FAIL\n", clockstring(clock_id)); + + if (delta_ns > max_latency_ns) + max_latency_ns = delta_ns; +} + +int do_timer(int clock_id, int flags) +{ + struct sigevent se; + timer_t tm1; + struct itimerspec its1, its2; + int err; + + /* Set up timer: */ + memset(&se, 0, sizeof(se)); + se.sigev_notify = SIGEV_SIGNAL; + se.sigev_signo = SIGRTMAX; + se.sigev_value.sival_int = 0; + + max_latency_ns = 0; + alarmcount = 0; + + err = timer_create(clock_id, &se, &tm1); + if (err) { + printf("%s - timer_create() failed\n", clockstring(clock_id)); + return -1; + } + + clock_gettime(clock_id, &start_time); + if (flags) { + its1.it_value = start_time; + its1.it_value.tv_sec += TIMER_SECS; + } else { + its1.it_value.tv_sec = TIMER_SECS; + its1.it_value.tv_nsec = 0; + } + its1.it_interval.tv_sec = TIMER_SECS; + its1.it_interval.tv_nsec = 0; + + err = timer_settime(tm1, flags, &its1, &its2); + if (err) { + printf("%s - timer_settime() failed\n", clockstring(clock_id)); + return -1; + } + + while (alarmcount < 5) + sleep(1); + + printf("%-22s %s max latency: %10lld ns : ", + clockstring(clock_id), + flags ? "ABSTIME":"RELTIME", + max_latency_ns); + + timer_delete(tm1); + if (max_latency_ns < UNRESONABLE_LATENCY) { + printf("[OK]\n"); + return 0; + } + printf("[FAILED]\n"); + return -1; +} + +int main(void) +{ + struct sigaction act; + int signum = SIGRTMAX; + int ret = 0; + + /* Set up signal handler: */ + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = sigalarm; + sigaction(signum, &act, NULL); + + printf("Setting timers for every %i seconds\n", TIMER_SECS); + for (clock_id = 0; clock_id < NR_CLOCKIDS; clock_id++) { + + if ((clock_id == CLOCK_PROCESS_CPUTIME_ID) || + (clock_id == CLOCK_THREAD_CPUTIME_ID) || + (clock_id == CLOCK_MONOTONIC_RAW) || + (clock_id == CLOCK_REALTIME_COARSE) || + (clock_id == CLOCK_MONOTONIC_COARSE) || + (clock_id == CLOCK_HWSPECIFIC)) + continue; + + ret |= do_timer(clock_id, TIMER_ABSTIME); + ret |= do_timer(clock_id, 0); + } + if (ret) + return ksft_exit_fail(); + return ksft_exit_pass(); +} -- cgit v1.1 From e39b60f37ecbdc0dd3dbc4c80407c6f2376f764f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:04 -0700 Subject: selftests/timers: Add threaded time inconsistency test from timetest suite Add the threaded time inconsistency test from the timetest suite. This checks for time inconsistencies between cpus, usually associated with clock skew as sometimes found w/ TSCs. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 4 +- tools/testing/selftests/timers/threadtest.c | 200 ++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/timers/threadtest.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index f69bdce..e53b675 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -3,7 +3,7 @@ BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ - set-timer-lat + set-timer-lat threadtest all: ${bins} @@ -14,6 +14,6 @@ run_tests: all ./set-timer-lat ./inconsistency-check ./raw_skew - + ./threadtest -t 30 -n 8 clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/threadtest.c b/tools/testing/selftests/timers/threadtest.c new file mode 100644 index 0000000..facd889 --- /dev/null +++ b/tools/testing/selftests/timers/threadtest.c @@ -0,0 +1,200 @@ +/* threadtest.c + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2004, 2005, 2006, 2012 + * Licensed under the GPLv2 + * + * To build: + * $ gcc threadtest.c -o threadtest -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + + +/* serializes shared list access */ +pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; +/* serializes console output */ +pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; + + +#define MAX_THREADS 128 +#define LISTSIZE 128 + +int done = 0; + +struct timespec global_list[LISTSIZE]; +int listcount = 0; + + +void checklist(struct timespec *list, int size) +{ + int i, j; + struct timespec *a, *b; + + /* scan the list */ + for (i = 0; i < size-1; i++) { + a = &list[i]; + b = &list[i+1]; + + /* look for any time inconsistencies */ + if ((b->tv_sec <= a->tv_sec) && + (b->tv_nsec < a->tv_nsec)) { + + /* flag other threads */ + done = 1; + + /*serialize printing to avoid junky output*/ + pthread_mutex_lock(&print_lock); + + /* dump the list */ + printf("\n"); + for (j = 0; j < size; j++) { + if (j == i) + printf("---------------\n"); + printf("%lu:%lu\n", list[j].tv_sec, list[j].tv_nsec); + if (j == i+1) + printf("---------------\n"); + } + printf("[FAILED]\n"); + + pthread_mutex_unlock(&print_lock); + } + } +} + +/* The shared thread shares a global list + * that each thread fills while holding the lock. + * This stresses clock syncronization across cpus. + */ +void *shared_thread(void *arg) +{ + while (!done) { + /* protect the list */ + pthread_mutex_lock(&list_lock); + + /* see if we're ready to check the list */ + if (listcount >= LISTSIZE) { + checklist(global_list, LISTSIZE); + listcount = 0; + } + clock_gettime(CLOCK_MONOTONIC, &global_list[listcount++]); + + pthread_mutex_unlock(&list_lock); + } + return NULL; +} + + +/* Each independent thread fills in its own + * list. This stresses clock_gettime() lock contention. + */ +void *independent_thread(void *arg) +{ + struct timespec my_list[LISTSIZE]; + int count; + + while (!done) { + /* fill the list */ + for (count = 0; count < LISTSIZE; count++) + clock_gettime(CLOCK_MONOTONIC, &my_list[count]); + checklist(my_list, LISTSIZE); + } + return NULL; +} + + +int main(int argc, char **argv) +{ + int thread_count = 1, i; + time_t start, now, runtime = 60; + char buf[255]; + pthread_t pth[MAX_THREADS]; + int opt; + void *tret; + int ret = 0; + void *(*thread)(void *) = shared_thread; + + + /* Process arguments */ + while ((opt = getopt(argc, argv, "t:n:i")) != -1) { + switch (opt) { + case 't': + runtime = atoi(optarg); + break; + case 'n': + thread_count = atoi(optarg); + break; + case 'i': + thread = independent_thread; + printf("using independent threads\n"); + break; + default: + printf("Usage: %s [-t ] [-n ] [-i]\n", argv[0]); + printf(" -t: time to run\n"); + printf(" -n: number of threads\n"); + printf(" -i: use independent threads\n"); + return -1; + } + } + + if (thread_count > MAX_THREADS) + thread_count = MAX_THREADS; + + + setbuf(stdout, NULL); + + start = time(0); + strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&start)); + printf("%s\n", buf); + printf("Testing consistency with %i threads for %ld seconds: ", thread_count, runtime); + + /* spawn */ + for (i = 0; i < thread_count; i++) + pthread_create(&pth[i], 0, thread, 0); + + while (time(&now) < start + runtime) { + sleep(1); + if (done) { + ret = 1; + strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&now)); + printf("%s\n", buf); + goto out; + } + } + printf("[OK]\n"); + done = 1; + +out: + /* wait */ + for (i = 0; i < thread_count; i++) + pthread_join(pth[i], &tret); + + /* die */ + if (ret) + ksft_exit_fail(); + return ksft_exit_pass(); +} -- cgit v1.1 From 274d631e481504e347b491ddb5e18487b855aba5 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:05 -0700 Subject: selftests/timers: Add mqueue latency test from the timetest suite Add test to validate mqueue timeout latency from the timetest suite Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/mqueue-lat.c | 124 ++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/mqueue-lat.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index e53b675..d0bfb2d 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -3,7 +3,7 @@ BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ - set-timer-lat threadtest + set-timer-lat threadtest mqueue-lat all: ${bins} @@ -12,6 +12,7 @@ run_tests: all ./nanosleep ./nsleep-lat ./set-timer-lat + ./mqueue-lat ./inconsistency-check ./raw_skew ./threadtest -t 30 -n 8 diff --git a/tools/testing/selftests/timers/mqueue-lat.c b/tools/testing/selftests/timers/mqueue-lat.c new file mode 100644 index 0000000..a2a3924 --- /dev/null +++ b/tools/testing/selftests/timers/mqueue-lat.c @@ -0,0 +1,124 @@ +/* Measure mqueue timeout latency + * by: john stultz (john.stultz@linaro.org) + * (C) Copyright Linaro 2013 + * + * Inspired with permission from example test by: + * Romain Francoise + * Licensed under the GPLv2 + * + * To build: + * $ gcc mqueue-lat.c -o mqueue-lat -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000ULL + +#define TARGET_TIMEOUT 100000000 /* 100ms in nanoseconds */ +#define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ + + +long long timespec_sub(struct timespec a, struct timespec b) +{ + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; + + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; + return ret; +} + +struct timespec timespec_add(struct timespec ts, unsigned long long ns) +{ + ts.tv_nsec += ns; + while (ts.tv_nsec >= NSEC_PER_SEC) { + ts.tv_nsec -= NSEC_PER_SEC; + ts.tv_sec++; + } + return ts; +} + +int mqueue_lat_test(void) +{ + + mqd_t q; + struct mq_attr attr; + struct timespec start, end, now, target; + int i, count, ret; + + q = mq_open("/foo", O_CREAT | O_RDONLY, 0666, NULL); + if (q < 0) { + perror("mq_open"); + return -1; + } + mq_getattr(q, &attr); + + + count = 100; + clock_gettime(CLOCK_MONOTONIC, &start); + + for (i = 0; i < count; i++) { + char buf[attr.mq_msgsize]; + + clock_gettime(CLOCK_REALTIME, &now); + target = now; + target = timespec_add(now, TARGET_TIMEOUT); /* 100ms */ + + ret = mq_timedreceive(q, buf, sizeof(buf), NULL, &target); + if (ret < 0 && errno != ETIMEDOUT) { + perror("mq_timedreceive"); + return -1; + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + + mq_close(q); + + if ((timespec_sub(start, end)/count) > TARGET_TIMEOUT + UNRESONABLE_LATENCY) + return -1; + + return 0; +} + +int main(int argc, char **argv) +{ + int ret; + + printf("Mqueue latency : "); + + ret = mqueue_lat_test(); + if (ret < 0) { + printf("[FAILED]\n"); + return ksft_exit_fail(); + } + printf("[OK]\n"); + return ksft_exit_pass(); +} -- cgit v1.1 From de52133f1892ed2c385655473df90f3d2797fff9 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:06 -0700 Subject: selftests/timers: Add adjtimex validation test from timetest suite This adds a adjtimex validation test which checks the behavior for a set of valida and invalid inputs. So far this only tests ADJ_FREQUENCY, but hopefully will grow. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 11 +- tools/testing/selftests/timers/valid-adjtimex.c | 202 ++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/valid-adjtimex.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index d0bfb2d..01b5a2e 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -3,10 +3,12 @@ BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ - set-timer-lat threadtest mqueue-lat + set-timer-lat threadtest mqueue-lat valid-adjtimex all: ${bins} +# these are all "safe" tests that don't modify +# system time or require escalated privledges run_tests: all ./posix_timers ./nanosleep @@ -16,5 +18,12 @@ run_tests: all ./inconsistency-check ./raw_skew ./threadtest -t 30 -n 8 + +# these tests require escalated privledges +# and may modify the system time or trigger +# other behavior like suspend +run_destructive_tests: all + ./valid-adjtimex + clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c new file mode 100644 index 0000000..e86d937 --- /dev/null +++ b/tools/testing/selftests/timers/valid-adjtimex.c @@ -0,0 +1,202 @@ +/* valid adjtimex test + * by: John Stultz + * (C) Copyright Linaro 2015 + * Licensed under the GPLv2 + * + * This test validates adjtimex interface with valid + * and invalid test data. + * + * Usage: valid-adjtimex + * + * To build: + * $ gcc valid-adjtimex.c -o valid-adjtimex -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000L + +/* clear NTP time_status & time_state */ +int clear_time_state(void) +{ + struct timex tx; + int ret; + + tx.modes = ADJ_STATUS; + tx.status = 0; + ret = adjtimex(&tx); + return ret; +} + +#define NUM_FREQ_VALID 32 +#define NUM_FREQ_OUTOFRANGE 4 +#define NUM_FREQ_INVALID 2 + +long valid_freq[NUM_FREQ_VALID] = { + -499<<16, + -450<<16, + -400<<16, + -350<<16, + -300<<16, + -250<<16, + -200<<16, + -150<<16, + -100<<16, + -75<<16, + -50<<16, + -25<<16, + -10<<16, + -5<<16, + -1<<16, + -1000, + 1<<16, + 5<<16, + 10<<16, + 25<<16, + 50<<16, + 75<<16, + 100<<16, + 150<<16, + 200<<16, + 250<<16, + 300<<16, + 350<<16, + 400<<16, + 450<<16, + 499<<16, +}; + +long outofrange_freq[NUM_FREQ_OUTOFRANGE] = { + -1000<<16, + -550<<16, + 550<<16, + 1000<<16, +}; + +#define LONG_MAX (~0UL>>1) +#define LONG_MIN (-LONG_MAX - 1) + +long invalid_freq[NUM_FREQ_INVALID] = { + LONG_MAX, + LONG_MIN, +}; + +int validate_freq(void) +{ + struct timex tx; + int ret, pass = 0; + int i; + + clear_time_state(); + + memset(&tx, 0, sizeof(struct timex)); + /* Set the leap second insert flag */ + + printf("Testing ADJ_FREQ... "); + for (i = 0; i < NUM_FREQ_VALID; i++) { + tx.modes = ADJ_FREQUENCY; + tx.freq = valid_freq[i]; + + ret = adjtimex(&tx); + if (ret < 0) { + printf("[FAIL]\n"); + printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", + valid_freq[i], valid_freq[i]>>16); + pass = -1; + goto out; + } + tx.modes = 0; + ret = adjtimex(&tx); + if (tx.freq != valid_freq[i]) { + printf("Warning: freq value %ld not what we set it (%ld)!\n", + tx.freq, valid_freq[i]); + } + } + for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) { + tx.modes = ADJ_FREQUENCY; + tx.freq = outofrange_freq[i]; + + ret = adjtimex(&tx); + if (ret < 0) { + printf("[FAIL]\n"); + printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", + outofrange_freq[i], outofrange_freq[i]>>16); + pass = -1; + goto out; + } + tx.modes = 0; + ret = adjtimex(&tx); + if (tx.freq == outofrange_freq[i]) { + printf("[FAIL]\n"); + printf("ERROR: out of range value %ld actually set!\n", + tx.freq); + pass = -1; + goto out; + } + } + + + if (sizeof(long) == 8) { /* this case only applies to 64bit systems */ + for (i = 0; i < NUM_FREQ_INVALID; i++) { + tx.modes = ADJ_FREQUENCY; + tx.freq = invalid_freq[i]; + ret = adjtimex(&tx); + if (ret >= 0) { + printf("[FAIL]\n"); + printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n", + invalid_freq[i]); + pass = -1; + goto out; + } + } + } + + printf("[OK]\n"); +out: + /* reset freq to zero */ + tx.modes = ADJ_FREQUENCY; + tx.freq = 0; + ret = adjtimex(&tx); + + return pass; +} + + +int main(int argc, char **argv) +{ + if (validate_freq()) + return ksft_exit_fail(); + + return ksft_exit_pass(); +} -- cgit v1.1 From b7bb8442fa902272ffe937a226829c9be7bfb14b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:07 -0700 Subject: selftests/timers: Add alarmtimer-suspend test from timetests suite This adds the alarmtimer-suspend test from the timetests suite, which tests that the alarmtimers wake the system up from suspend shortly after the time they were set to fire. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 6 +- .../testing/selftests/timers/alarmtimer-suspend.c | 185 +++++++++++++++++++++ 2 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/timers/alarmtimer-suspend.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 01b5a2e..61a39ec 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -3,7 +3,8 @@ BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ - set-timer-lat threadtest mqueue-lat valid-adjtimex + set-timer-lat threadtest mqueue-lat valid-adjtimex \ + alarmtimer-suspend all: ${bins} @@ -22,7 +23,8 @@ run_tests: all # these tests require escalated privledges # and may modify the system time or trigger # other behavior like suspend -run_destructive_tests: all +run_destructive_tests: run_tests + ./alarmtimer-suspend ./valid-adjtimex clean: diff --git a/tools/testing/selftests/timers/alarmtimer-suspend.c b/tools/testing/selftests/timers/alarmtimer-suspend.c new file mode 100644 index 0000000..aaffbde --- /dev/null +++ b/tools/testing/selftests/timers/alarmtimer-suspend.c @@ -0,0 +1,185 @@ +/* alarmtimer suspend test + * John Stultz (john.stultz@linaro.org) + * (C) Copyright Linaro 2013 + * Licensed under the GPLv2 + * + * This test makes sure the alarmtimer & RTC wakeup code is + * functioning. + * + * To build: + * $ gcc alarmtimer-suspend.c -o alarmtimer-suspend -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 +#define CLOCK_REALTIME_COARSE 5 +#define CLOCK_MONOTONIC_COARSE 6 +#define CLOCK_BOOTTIME 7 +#define CLOCK_REALTIME_ALARM 8 +#define CLOCK_BOOTTIME_ALARM 9 +#define CLOCK_HWSPECIFIC 10 +#define CLOCK_TAI 11 +#define NR_CLOCKIDS 12 + + +#define NSEC_PER_SEC 1000000000ULL +#define UNREASONABLE_LAT (NSEC_PER_SEC * 4) /* hopefully we resume in 4secs */ + +#define SUSPEND_SECS 15 +int alarmcount; +int alarm_clock_id; +struct timespec start_time; + + +char *clockstring(int clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + }; + return "UNKNOWN_CLOCKID"; +} + + +long long timespec_sub(struct timespec a, struct timespec b) +{ + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; + + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; + return ret; +} + +int final_ret = 0; + +void sigalarm(int signo) +{ + long long delta_ns; + struct timespec ts; + + clock_gettime(alarm_clock_id, &ts); + alarmcount++; + + delta_ns = timespec_sub(start_time, ts); + delta_ns -= NSEC_PER_SEC * SUSPEND_SECS * alarmcount; + + printf("ALARM(%i): %ld:%ld latency: %lld ns ", alarmcount, ts.tv_sec, + ts.tv_nsec, delta_ns); + + if (delta_ns > UNREASONABLE_LAT) { + printf("[FAIL]\n"); + final_ret = -1; + } else + printf("[OK]\n"); + +} + +int main(void) +{ + timer_t tm1; + struct itimerspec its1, its2; + struct sigevent se; + struct sigaction act; + int signum = SIGRTMAX; + + /* Set up signal handler: */ + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = sigalarm; + sigaction(signum, &act, NULL); + + /* Set up timer: */ + memset(&se, 0, sizeof(se)); + se.sigev_notify = SIGEV_SIGNAL; + se.sigev_signo = signum; + se.sigev_value.sival_int = 0; + + for (alarm_clock_id = CLOCK_REALTIME_ALARM; + alarm_clock_id <= CLOCK_BOOTTIME_ALARM; + alarm_clock_id++) { + + alarmcount = 0; + timer_create(alarm_clock_id, &se, &tm1); + + clock_gettime(alarm_clock_id, &start_time); + printf("Start time (%s): %ld:%ld\n", clockstring(alarm_clock_id), + start_time.tv_sec, start_time.tv_nsec); + printf("Setting alarm for every %i seconds\n", SUSPEND_SECS); + its1.it_value = start_time; + its1.it_value.tv_sec += SUSPEND_SECS; + its1.it_interval.tv_sec = SUSPEND_SECS; + its1.it_interval.tv_nsec = 0; + + timer_settime(tm1, TIMER_ABSTIME, &its1, &its2); + + while (alarmcount < 5) + sleep(1); /* First 5 alarms, do nothing */ + + printf("Starting suspend loops\n"); + while (alarmcount < 10) { + int ret; + + sleep(1); + ret = system("echo mem > /sys/power/state"); + if (ret) + break; + } + timer_delete(tm1); + } + if (final_ret) + return ksft_exit_fail(); + return ksft_exit_pass(); +} -- cgit v1.1 From d869424558419a4a34a12bd5187b5d6d06ee132f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:08 -0700 Subject: selftests/timers: Add change_skew test from timetest suite This patch adds the change_skew test which validates the adjtimex freq can be set to various values and then using the inconsistency-check, raw_skew, and nanosleep tests ensures time behaves properly. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/change_skew.c | 107 +++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/change_skew.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 61a39ec..55b74cc 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -4,7 +4,7 @@ CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ - alarmtimer-suspend + alarmtimer-suspend change_skew all: ${bins} @@ -26,6 +26,7 @@ run_tests: all run_destructive_tests: run_tests ./alarmtimer-suspend ./valid-adjtimex + ./change_skew clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/change_skew.c b/tools/testing/selftests/timers/change_skew.c new file mode 100644 index 0000000..cb19689 --- /dev/null +++ b/tools/testing/selftests/timers/change_skew.c @@ -0,0 +1,107 @@ +/* ADJ_FREQ Skew change test + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2012 + * Licensed under the GPLv2 + * + * NOTE: This is a meta-test which cranks the ADJ_FREQ knob and + * then uses other tests to detect problems. Thus this test requires + * that the raw_skew, inconsistency-check and nanosleep tests be + * present in the same directory it is run from. + * + * To build: + * $ gcc change_skew.c -o change_skew -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000LL + + +int change_skew_test(int ppm) +{ + struct timex tx; + int ret; + + tx.modes = ADJ_FREQUENCY; + tx.freq = ppm << 16; + + ret = adjtimex(&tx); + if (ret < 0) { + printf("Error adjusting freq\n"); + return ret; + } + + ret = system("./raw_skew"); + ret |= system("./inconsistency-check"); + ret |= system("./nanosleep"); + + return ret; +} + + +int main(int argv, char **argc) +{ + struct timex tx; + int i, ret; + + int ppm[5] = {0, 250, 500, -250, -500}; + + /* Kill ntpd */ + ret = system("killall -9 ntpd"); + + /* Make sure there's no offset adjustment going on */ + tx.modes = ADJ_OFFSET; + tx.offset = 0; + ret = adjtimex(&tx); + + if (ret < 0) { + printf("Maybe you're not running as root?\n"); + return -1; + } + + for (i = 0; i < 5; i++) { + printf("Using %i ppm adjustment\n", ppm[i]); + ret = change_skew_test(ppm[i]); + if (ret) + break; + } + + /* Set things back */ + tx.modes = ADJ_FREQUENCY; + tx.offset = 0; + adjtimex(&tx); + + if (ret) { + printf("[FAIL]"); + return ksft_exit_fail(); + } + printf("[OK]"); + return ksft_exit_pass(); +} -- cgit v1.1 From 6e8b285bcdd1834a18fd264c88a15418091c4015 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:09 -0700 Subject: selftests/timers: Add skew_consistency test from the timetests suite This change adds the skew_consistency test, which twists the ADJ_FREQUENCY knob back and forth and watches for timekeeping inconsistencies. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/skew_consistency.c | 89 +++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/skew_consistency.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 55b74cc..4b6b5c3 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -4,7 +4,7 @@ CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ - alarmtimer-suspend change_skew + alarmtimer-suspend change_skew skew_consistency all: ${bins} @@ -27,6 +27,7 @@ run_destructive_tests: run_tests ./alarmtimer-suspend ./valid-adjtimex ./change_skew + ./skew_consistency clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/skew_consistency.c b/tools/testing/selftests/timers/skew_consistency.c new file mode 100644 index 0000000..5562f84 --- /dev/null +++ b/tools/testing/selftests/timers/skew_consistency.c @@ -0,0 +1,89 @@ +/* ADJ_FREQ Skew consistency test + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2012 + * Licensed under the GPLv2 + * + * NOTE: This is a meta-test which cranks the ADJ_FREQ knob back + * and forth and watches for consistency problems. Thus this test requires + * that the inconsistency-check tests be present in the same directory it + * is run from. + * + * To build: + * $ gcc skew_consistency.c -o skew_consistency -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000LL + +int main(int argv, char **argc) +{ + struct timex tx; + int ret, ppm; + pid_t pid; + + + printf("Running Asyncrhonous Frequency Changing Tests...\n"); + + pid = fork(); + if (!pid) + return system("./inconsistency-check -c 1 -t 600"); + + ppm = 500; + ret = 0; + + while (pid != waitpid(pid, &ret, WNOHANG)) { + ppm = -ppm; + tx.modes = ADJ_FREQUENCY; + tx.freq = ppm << 16; + adjtimex(&tx); + usleep(500000); + } + + /* Set things back */ + tx.modes = ADJ_FREQUENCY; + tx.offset = 0; + adjtimex(&tx); + + + if (ret) { + printf("[FAILED]\n"); + return ksft_exit_fail(); + } + printf("[OK]\n"); + return ksft_exit_pass(); +} -- cgit v1.1 From 7290ce1423c38108027ae90116ece6618db32bc3 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:10 -0700 Subject: selftests/timers: Add clocksource-switch test from timetest suite Adds the clocksource-switch tests which continually switches the current clocksource between all the available ones, watching for any timekeeping inconsistencies. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- .../testing/selftests/timers/clocksource-switch.c | 179 +++++++++++++++++++++ 2 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/clocksource-switch.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 4b6b5c3..4a006d7 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -4,7 +4,7 @@ CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ - alarmtimer-suspend change_skew skew_consistency + alarmtimer-suspend change_skew skew_consistency clocksource-switch \ all: ${bins} @@ -28,6 +28,7 @@ run_destructive_tests: run_tests ./valid-adjtimex ./change_skew ./skew_consistency + ./clocksource-switch clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c new file mode 100644 index 0000000..627ec74 --- /dev/null +++ b/tools/testing/selftests/timers/clocksource-switch.c @@ -0,0 +1,179 @@ +/* Clocksource change test + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2012 + * Licensed under the GPLv2 + * + * NOTE: This is a meta-test which quickly changes the clocksourc and + * then uses other tests to detect problems. Thus this test requires + * that the inconsistency-check and nanosleep tests be present in the + * same directory it is run from. + * + * To build: + * $ gcc clocksource-switch.c -o clocksource-switch -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + + +int get_clocksources(char list[][30]) +{ + int fd, i; + size_t size; + char buf[512]; + char *head, *tmp; + + fd = open("/sys/devices/system/clocksource/clocksource0/available_clocksource", O_RDONLY); + + size = read(fd, buf, 512); + + close(fd); + + for (i = 0; i < 30; i++) + list[i][0] = '\0'; + + head = buf; + i = 0; + while (head - buf < size) { + /* Find the next space */ + for (tmp = head; *tmp != ' '; tmp++) { + if (*tmp == '\n') + break; + if (*tmp == '\0') + break; + } + *tmp = '\0'; + strcpy(list[i], head); + head = tmp + 1; + i++; + } + + return i-1; +} + +int get_cur_clocksource(char *buf, size_t size) +{ + int fd; + + fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_RDONLY); + + size = read(fd, buf, size); + + return 0; +} + +int change_clocksource(char *clocksource) +{ + int fd; + size_t size; + + fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY); + + if (fd < 0) + return -1; + + size = write(fd, clocksource, strlen(clocksource)); + + if (size < 0) + return -1; + + close(fd); + return 0; +} + + +int run_tests(int secs) +{ + int ret; + char buf[255]; + + sprintf(buf, "./inconsistency-check -t %i", secs); + ret = system(buf); + if (ret) + return ret; + ret = system("./nanosleep"); + return ret; +} + + +char clocksource_list[10][30]; + +int main(int argv, char **argc) +{ + char orig_clk[512]; + int count, i, status; + pid_t pid; + + get_cur_clocksource(orig_clk, 512); + + count = get_clocksources(clocksource_list); + + if (change_clocksource(clocksource_list[0])) { + printf("Error: You probably need to run this as root\n"); + return -1; + } + + /* Check everything is sane before we start switching asyncrhonously */ + for (i = 0; i < count; i++) { + printf("Validating clocksource %s\n", clocksource_list[i]); + if (change_clocksource(clocksource_list[i])) { + status = -1; + goto out; + } + if (run_tests(5)) { + status = -1; + goto out; + } + } + + + printf("Running Asyncrhonous Switching Tests...\n"); + pid = fork(); + if (!pid) + return run_tests(60); + + while (pid != waitpid(pid, &status, WNOHANG)) + for (i = 0; i < count; i++) + if (change_clocksource(clocksource_list[i])) { + status = -1; + goto out; + } +out: + change_clocksource(orig_clk); + + if (status) + return ksft_exit_fail(); + return ksft_exit_pass(); +} -- cgit v1.1 From 5bccfe41532f4b80fc70cd8f78fd965666a46c15 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:11 -0700 Subject: selftests/timers: Add leap-a-day test from timetest suite This change adds the leap-a-day test which sets STA_INS and STA_DEL each day to trigger leapseconds each day. It also has a mode to jump the time to right before the end of the day each iteration. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 2 + tools/testing/selftests/timers/leap-a-day.c | 319 ++++++++++++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 tools/testing/selftests/timers/leap-a-day.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 4a006d7..da35ddd 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -5,6 +5,7 @@ LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ alarmtimer-suspend change_skew skew_consistency clocksource-switch \ + leap-a-day all: ${bins} @@ -29,6 +30,7 @@ run_destructive_tests: run_tests ./change_skew ./skew_consistency ./clocksource-switch + ./leap-a-day -s -i 10 clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/leap-a-day.c b/tools/testing/selftests/timers/leap-a-day.c new file mode 100644 index 0000000..b8272e6 --- /dev/null +++ b/tools/testing/selftests/timers/leap-a-day.c @@ -0,0 +1,319 @@ +/* Leap second stress test + * by: John Stultz (john.stultz@linaro.org) + * (C) Copyright IBM 2012 + * (C) Copyright 2013, 2015 Linaro Limited + * Licensed under the GPLv2 + * + * This test signals the kernel to insert a leap second + * every day at midnight GMT. This allows for stessing the + * kernel's leap-second behavior, as well as how well applications + * handle the leap-second discontinuity. + * + * Usage: leap-a-day [-s] [-i ] + * + * Options: + * -s: Each iteration, set the date to 10 seconds before midnight GMT. + * This speeds up the number of leapsecond transitions tested, + * but because it calls settimeofday frequently, advancing the + * time by 24 hours every ~16 seconds, it may cause application + * disruption. + * + * -i: Number of iterations to run (default: infinite) + * + * Other notes: Disabling NTP prior to running this is advised, as the two + * may conflict in their commands to the kernel. + * + * To build: + * $ gcc leap-a-day.c -o leap-a-day -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000ULL +#define CLOCK_TAI 11 + +/* returns 1 if a <= b, 0 otherwise */ +static inline int in_order(struct timespec a, struct timespec b) +{ + if (a.tv_sec < b.tv_sec) + return 1; + if (a.tv_sec > b.tv_sec) + return 0; + if (a.tv_nsec > b.tv_nsec) + return 0; + return 1; +} + +struct timespec timespec_add(struct timespec ts, unsigned long long ns) +{ + ts.tv_nsec += ns; + while (ts.tv_nsec >= NSEC_PER_SEC) { + ts.tv_nsec -= NSEC_PER_SEC; + ts.tv_sec++; + } + return ts; +} + +char *time_state_str(int state) +{ + switch (state) { + case TIME_OK: return "TIME_OK"; + case TIME_INS: return "TIME_INS"; + case TIME_DEL: return "TIME_DEL"; + case TIME_OOP: return "TIME_OOP"; + case TIME_WAIT: return "TIME_WAIT"; + case TIME_BAD: return "TIME_BAD"; + } + return "ERROR"; +} + +/* clear NTP time_status & time_state */ +int clear_time_state(void) +{ + struct timex tx; + int ret; + + /* + * We have to call adjtime twice here, as kernels + * prior to 6b1859dba01c7 (included in 3.5 and + * -stable), had an issue with the state machine + * and wouldn't clear the STA_INS/DEL flag directly. + */ + tx.modes = ADJ_STATUS; + tx.status = STA_PLL; + ret = adjtimex(&tx); + + /* Clear maxerror, as it can cause UNSYNC to be set */ + tx.modes = ADJ_MAXERROR; + tx.maxerror = 0; + ret = adjtimex(&tx); + + /* Clear the status */ + tx.modes = ADJ_STATUS; + tx.status = 0; + ret = adjtimex(&tx); + + return ret; +} + +/* Make sure we cleanup on ctrl-c */ +void handler(int unused) +{ + clear_time_state(); + exit(0); +} + +/* Test for known hrtimer failure */ +void test_hrtimer_failure(void) +{ + struct timespec now, target; + + clock_gettime(CLOCK_REALTIME, &now); + target = timespec_add(now, NSEC_PER_SEC/2); + clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL); + clock_gettime(CLOCK_REALTIME, &now); + + if (!in_order(target, now)) + printf("ERROR: hrtimer early expiration failure observed.\n"); +} + +int main(int argc, char **argv) +{ + int settime = 0; + int tai_time = 0; + int insert = 1; + int iterations = -1; + int opt; + + /* Process arguments */ + while ((opt = getopt(argc, argv, "sti:")) != -1) { + switch (opt) { + case 's': + printf("Setting time to speed up testing\n"); + settime = 1; + break; + case 'i': + iterations = atoi(optarg); + break; + case 't': + tai_time = 1; + break; + default: + printf("Usage: %s [-s] [-i ]\n", argv[0]); + printf(" -s: Set time to right before leap second each iteration\n"); + printf(" -i: Number of iterations\n"); + printf(" -t: Print TAI time\n"); + exit(-1); + } + } + + /* Make sure TAI support is present if -t was used */ + if (tai_time) { + struct timespec ts; + + if (clock_gettime(CLOCK_TAI, &ts)) { + printf("System doesn't support CLOCK_TAI\n"); + ksft_exit_fail(); + } + } + + signal(SIGINT, handler); + signal(SIGKILL, handler); + + if (iterations < 0) + printf("This runs continuously. Press ctrl-c to stop\n"); + else + printf("Running for %i iterations. Press ctrl-c to stop\n", iterations); + + printf("\n"); + while (1) { + int ret; + struct timespec ts; + struct timex tx; + time_t now, next_leap; + + /* Get the current time */ + clock_gettime(CLOCK_REALTIME, &ts); + + /* Calculate the next possible leap second 23:59:60 GMT */ + next_leap = ts.tv_sec; + next_leap += 86400 - (next_leap % 86400); + + if (settime) { + struct timeval tv; + + tv.tv_sec = next_leap - 10; + tv.tv_usec = 0; + settimeofday(&tv, NULL); + printf("Setting time to %s", ctime(&tv.tv_sec)); + } + + /* Reset NTP time state */ + clear_time_state(); + + /* Set the leap second insert flag */ + tx.modes = ADJ_STATUS; + if (insert) + tx.status = STA_INS; + else + tx.status = STA_DEL; + ret = adjtimex(&tx); + if (ret < 0) { + printf("Error: Problem setting STA_INS/STA_DEL!: %s\n", + time_state_str(ret)); + return ksft_exit_fail(); + } + + /* Validate STA_INS was set */ + tx.modes = 0; + ret = adjtimex(&tx); + if (tx.status != STA_INS && tx.status != STA_DEL) { + printf("Error: STA_INS/STA_DEL not set!: %s\n", + time_state_str(ret)); + return ksft_exit_fail(); + } + + if (tai_time) { + printf("Using TAI time," + " no inconsistencies should be seen!\n"); + } + + printf("Scheduling leap second for %s", ctime(&next_leap)); + + /* Wake up 3 seconds before leap */ + ts.tv_sec = next_leap - 3; + ts.tv_nsec = 0; + + while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL)) + printf("Something woke us up, returning to sleep\n"); + + /* Validate STA_INS is still set */ + tx.modes = 0; + ret = adjtimex(&tx); + if (tx.status != STA_INS && tx.status != STA_DEL) { + printf("Something cleared STA_INS/STA_DEL, setting it again.\n"); + tx.modes = ADJ_STATUS; + if (insert) + tx.status = STA_INS; + else + tx.status = STA_DEL; + ret = adjtimex(&tx); + } + + /* Check adjtimex output every half second */ + now = tx.time.tv_sec; + while (now < next_leap + 2) { + char buf[26]; + struct timespec tai; + + tx.modes = 0; + ret = adjtimex(&tx); + + if (tai_time) { + clock_gettime(CLOCK_TAI, &tai); + printf("%ld sec, %9ld ns\t%s\n", + tai.tv_sec, + tai.tv_nsec, + time_state_str(ret)); + } else { + ctime_r(&tx.time.tv_sec, buf); + buf[strlen(buf)-1] = 0; /*remove trailing\n */ + + printf("%s + %6ld us (%i)\t%s\n", + buf, + tx.time.tv_usec, + tx.tai, + time_state_str(ret)); + } + now = tx.time.tv_sec; + /* Sleep for another half second */ + ts.tv_sec = 0; + ts.tv_nsec = NSEC_PER_SEC / 2; + clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + } + /* Switch to using other mode */ + insert = !insert; + + /* Note if kernel has known hrtimer failure */ + test_hrtimer_failure(); + + printf("Leap complete\n\n"); + + if ((iterations != -1) && !(--iterations)) + break; + } + + clear_time_state(); + return ksft_exit_pass(); +} -- cgit v1.1 From d7b2902c1541f8e65186c4e9dd1bf054b45d49e5 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:12 -0700 Subject: selftests/timers: Add leapcrash test from the timetest suite This change adds the leapcrash test which tests to see if a leapsecond deadlock which was observed from 2.6.26 to 3.3 is present on this system. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/leapcrash.c | 120 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/leapcrash.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index da35ddd..d733324 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -5,7 +5,7 @@ LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ alarmtimer-suspend change_skew skew_consistency clocksource-switch \ - leap-a-day + leap-a-day leapcrash all: ${bins} @@ -31,6 +31,7 @@ run_destructive_tests: run_tests ./skew_consistency ./clocksource-switch ./leap-a-day -s -i 10 + ./leapcrash clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/leapcrash.c b/tools/testing/selftests/timers/leapcrash.c new file mode 100644 index 0000000..a1071bd --- /dev/null +++ b/tools/testing/selftests/timers/leapcrash.c @@ -0,0 +1,120 @@ +/* Demo leapsecond deadlock + * by: John Stultz (john.stultz@linaro.org) + * (C) Copyright IBM 2012 + * (C) Copyright 2013, 2015 Linaro Limited + * Licensed under the GPL + * + * This test demonstrates leapsecond deadlock that is possibe + * on kernels from 2.6.26 to 3.3. + * + * WARNING: THIS WILL LIKELY HARDHANG SYSTEMS AND MAY LOSE DATA + * RUN AT YOUR OWN RISK! + * To build: + * $ gcc leapcrash.c -o leapcrash -lrt + */ + + + +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + + + +/* clear NTP time_status & time_state */ +int clear_time_state(void) +{ + struct timex tx; + int ret; + + /* + * We have to call adjtime twice here, as kernels + * prior to 6b1859dba01c7 (included in 3.5 and + * -stable), had an issue with the state machine + * and wouldn't clear the STA_INS/DEL flag directly. + */ + tx.modes = ADJ_STATUS; + tx.status = STA_PLL; + ret = adjtimex(&tx); + + tx.modes = ADJ_STATUS; + tx.status = 0; + ret = adjtimex(&tx); + + return ret; +} + +/* Make sure we cleanup on ctrl-c */ +void handler(int unused) +{ + clear_time_state(); + exit(0); +} + + +int main(void) +{ + struct timex tx; + struct timespec ts; + time_t next_leap; + int count = 0; + + setbuf(stdout, NULL); + + signal(SIGINT, handler); + signal(SIGKILL, handler); + printf("This runs for a few minutes. Press ctrl-c to stop\n"); + + clear_time_state(); + + + /* Get the current time */ + clock_gettime(CLOCK_REALTIME, &ts); + + /* Calculate the next possible leap second 23:59:60 GMT */ + next_leap = ts.tv_sec; + next_leap += 86400 - (next_leap % 86400); + + for (count = 0; count < 20; count++) { + struct timeval tv; + + + /* set the time to 2 seconds before the leap */ + tv.tv_sec = next_leap - 2; + tv.tv_usec = 0; + if (settimeofday(&tv, NULL)) { + printf("Error: You're likely not running with proper (ie: root) permissions\n"); + return ksft_exit_fail(); + } + tx.modes = 0; + adjtimex(&tx); + + /* hammer on adjtime w/ STA_INS */ + while (tx.time.tv_sec < next_leap + 1) { + /* Set the leap second insert flag */ + tx.modes = ADJ_STATUS; + tx.status = STA_INS; + adjtimex(&tx); + } + clear_time_state(); + printf("."); + } + printf("[OK]\n"); + return ksft_exit_pass(); +} -- cgit v1.1 From 3a92a15fba68b5c9c8b51ee98a94a3d1ff54c8e5 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:13 -0700 Subject: selftests/timers: Add set-tai from the timetest suite This patch adds the set-tai test which ensures the tai offset can be set properly from adjtimex. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/set-tai.c | 79 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/set-tai.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index d733324..7e2fba7 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -5,7 +5,7 @@ LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ alarmtimer-suspend change_skew skew_consistency clocksource-switch \ - leap-a-day leapcrash + leap-a-day leapcrash set-tai all: ${bins} @@ -32,6 +32,7 @@ run_destructive_tests: run_tests ./clocksource-switch ./leap-a-day -s -i 10 ./leapcrash + ./set-tai clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/set-tai.c b/tools/testing/selftests/timers/set-tai.c new file mode 100644 index 0000000..dc88dbc --- /dev/null +++ b/tools/testing/selftests/timers/set-tai.c @@ -0,0 +1,79 @@ +/* Set tai offset + * by: John Stultz + * (C) Copyright Linaro 2013 + * Licensed under the GPLv2 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +int set_tai(int offset) +{ + struct timex tx; + + memset(&tx, 0, sizeof(tx)); + + tx.modes = ADJ_TAI; + tx.constant = offset; + + return adjtimex(&tx); +} + +int get_tai(void) +{ + struct timex tx; + + memset(&tx, 0, sizeof(tx)); + + adjtimex(&tx); + return tx.tai; +} + +int main(int argc, char **argv) +{ + int i, ret; + + ret = get_tai(); + printf("tai offset started at %i\n", ret); + + printf("Checking tai offsets can be properly set: "); + for (i = 1; i <= 60; i++) { + ret = set_tai(i); + ret = get_tai(); + if (ret != i) { + printf("[FAILED] expected: %i got %i\n", i, ret); + return ksft_exit_fail(); + } + } + printf("[OK]\n"); + return ksft_exit_pass(); +} -- cgit v1.1 From 0d02a753a5f61cc5b57b83d8bd709cb64fe7e81f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:14 -0700 Subject: selftests/timers: Add set-2038 test from timetest suite Adds the set-2038 test which sets the time to near-edge cases like the start and end of the 32 bit epoch and checks that time behaves properly. There is also a dangerous mode, which lets the clock roll over past 2038 on 32bit systems, which on some older kernels will cause system hangs. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/Makefile | 3 +- tools/testing/selftests/timers/set-2038.c | 144 ++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/timers/set-2038.c diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 7e2fba7..9da3498 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -5,7 +5,7 @@ LDFLAGS += -lrt -lpthread bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ set-timer-lat threadtest mqueue-lat valid-adjtimex \ alarmtimer-suspend change_skew skew_consistency clocksource-switch \ - leap-a-day leapcrash set-tai + leap-a-day leapcrash set-tai set-2038 all: ${bins} @@ -33,6 +33,7 @@ run_destructive_tests: run_tests ./leap-a-day -s -i 10 ./leapcrash ./set-tai + ./set-2038 clean: rm -f ${bins} diff --git a/tools/testing/selftests/timers/set-2038.c b/tools/testing/selftests/timers/set-2038.c new file mode 100644 index 0000000..c8a7e14 --- /dev/null +++ b/tools/testing/selftests/timers/set-2038.c @@ -0,0 +1,144 @@ +/* Time bounds setting test + * by: john stultz (johnstul@us.ibm.com) + * (C) Copyright IBM 2012 + * Licensed under the GPLv2 + * + * NOTE: This is a meta-test which sets the time to edge cases then + * uses other tests to detect problems. Thus this test requires that + * the inconsistency-check and nanosleep tests be present in the same + * directory it is run from. + * + * To build: + * $ gcc set-2038.c -o set-2038 -lrt + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#ifdef KTEST +#include "../kselftest.h" +#else +static inline int ksft_exit_pass(void) +{ + exit(0); +} +static inline int ksft_exit_fail(void) +{ + exit(1); +} +#endif + +#define NSEC_PER_SEC 1000000000LL + +#define KTIME_MAX ((long long)~((unsigned long long)1 << 63)) +#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) + +#define YEAR_1901 (-0x7fffffffL) +#define YEAR_1970 1 +#define YEAR_2038 0x7fffffffL /*overflows 32bit time_t */ +#define YEAR_2262 KTIME_SEC_MAX /*overflows 64bit ktime_t */ +#define YEAR_MAX ((long long)((1ULL<<63)-1)) /*overflows 64bit time_t */ + +int is32bits(void) +{ + return (sizeof(long) == 4); +} + +int settime(long long time) +{ + struct timeval now; + int ret; + + now.tv_sec = (time_t)time; + now.tv_usec = 0; + + ret = settimeofday(&now, NULL); + + printf("Setting time to 0x%lx: %d\n", (long)time, ret); + return ret; +} + +int do_tests(void) +{ + int ret; + + ret = system("date"); + ret = system("./inconsistency-check -c 0 -t 20"); + ret |= system("./nanosleep"); + ret |= system("./nsleep-lat"); + return ret; + +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int opt, dangerous = 0; + time_t start; + + /* Process arguments */ + while ((opt = getopt(argc, argv, "d")) != -1) { + switch (opt) { + case 'd': + dangerous = 1; + } + } + + start = time(0); + + /* First test that crazy values don't work */ + if (!settime(YEAR_1901)) { + ret = -1; + goto out; + } + if (!settime(YEAR_MAX)) { + ret = -1; + goto out; + } + if (!is32bits() && !settime(YEAR_2262)) { + ret = -1; + goto out; + } + + /* Now test behavior near edges */ + settime(YEAR_1970); + ret = do_tests(); + if (ret) + goto out; + + settime(YEAR_2038 - 600); + ret = do_tests(); + if (ret) + goto out; + + /* The rest of the tests can blowup on 32bit systems */ + if (is32bits() && !dangerous) + goto out; + /* Test rollover behavior 32bit edge */ + settime(YEAR_2038 - 10); + ret = do_tests(); + if (ret) + goto out; + + settime(YEAR_2262 - 600); + ret = do_tests(); + +out: + /* restore clock */ + settime(start); + if (ret) + return ksft_exit_fail(); + return ksft_exit_pass(); +} -- cgit v1.1 From 7fe5f1c16c2c7904c7b8fcfb93e691893f21e8d3 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 11 Mar 2015 17:40:15 -0700 Subject: MAINTAINERS: Add selftests/timers to the timekeeping maintainance list Since I'm adding a bunch of tests to selftests/timers, put me on the hook in the maintainers file. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Tested-by: Prarit Bhargava Signed-off-by: Shuah Khan --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6239a30..8454a3c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8542,6 +8542,7 @@ F: include/uapi/linux/timex.h F: kernel/time/clocksource.c F: kernel/time/time*.c F: kernel/time/ntp.c +F: tools/testing/selftests/timers/ SC1200 WDT DRIVER M: Zwane Mwaikambo -- cgit v1.1 From 5e29a9105b1a0da86eff0ad6ae015997b49d4d1d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 11 Mar 2015 15:05:59 +1100 Subject: selftests: Introduce minimal shared logic for running tests This adds a Make include file which most selftests can then include to get the run_tests logic. On its own this has the advantage of some reduction in repetition, and also means the pass/fail message is defined in fewer places. However the key advantage is it will allow us to implement install very simply in a subsequent patch. The default implementation just executes each program in $(TEST_PROGS). We use a variable to hold the default implementation of $(RUN_TESTS) because that gives us a clean way to override it if necessary, ie. using override. The mount, memory-hotplug and mqueue tests use that to provide a different implementation. Tests are not run via /bin/bash, so if they are scripts they must be executable, we add a+x to several. Signed-off-by: Michael Ellerman Signed-off-by: Shuah Khan --- tools/testing/selftests/breakpoints/Makefile | 5 +++-- tools/testing/selftests/cpu-hotplug/Makefile | 5 +++-- tools/testing/selftests/cpu-hotplug/on-off-test.sh | 0 tools/testing/selftests/efivarfs/Makefile | 5 +++-- tools/testing/selftests/efivarfs/efivarfs.sh | 0 tools/testing/selftests/exec/Makefile | 5 +++-- tools/testing/selftests/firmware/Makefile | 20 ++------------------ tools/testing/selftests/firmware/fw_filesystem.sh | 0 tools/testing/selftests/firmware/fw_userhelper.sh | 0 tools/testing/selftests/ftrace/Makefile | 5 +++-- tools/testing/selftests/ipc/Makefile | 5 +++-- tools/testing/selftests/kcmp/Makefile | 5 +++-- tools/testing/selftests/lib.mk | 10 ++++++++++ tools/testing/selftests/memfd/Makefile | 6 +++--- tools/testing/selftests/memory-hotplug/Makefile | 5 +++-- .../testing/selftests/memory-hotplug/on-off-test.sh | 0 tools/testing/selftests/mount/Makefile | 8 ++------ tools/testing/selftests/mqueue/Makefile | 9 ++++++--- tools/testing/selftests/net/Makefile | 8 ++++---- tools/testing/selftests/net/run_afpackettests | 0 tools/testing/selftests/net/run_netsocktests | 0 tools/testing/selftests/ptrace/Makefile | 5 +++-- tools/testing/selftests/size/Makefile | 5 +++-- tools/testing/selftests/sysctl/Makefile | 11 ++--------- tools/testing/selftests/sysctl/run_numerictests | 0 tools/testing/selftests/sysctl/run_stringtests | 0 tools/testing/selftests/user/Makefile | 5 +++-- tools/testing/selftests/vm/Makefile | 5 +++-- tools/testing/selftests/vm/run_vmtests | 0 29 files changed, 65 insertions(+), 67 deletions(-) mode change 100644 => 100755 tools/testing/selftests/cpu-hotplug/on-off-test.sh mode change 100644 => 100755 tools/testing/selftests/efivarfs/efivarfs.sh mode change 100644 => 100755 tools/testing/selftests/firmware/fw_filesystem.sh mode change 100644 => 100755 tools/testing/selftests/firmware/fw_userhelper.sh create mode 100644 tools/testing/selftests/lib.mk mode change 100644 => 100755 tools/testing/selftests/memory-hotplug/on-off-test.sh mode change 100644 => 100755 tools/testing/selftests/net/run_afpackettests mode change 100644 => 100755 tools/testing/selftests/net/run_netsocktests mode change 100644 => 100755 tools/testing/selftests/sysctl/run_numerictests mode change 100644 => 100755 tools/testing/selftests/sysctl/run_stringtests mode change 100644 => 100755 tools/testing/selftests/vm/run_vmtests diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile index e18b42b..1822356 100644 --- a/tools/testing/selftests/breakpoints/Makefile +++ b/tools/testing/selftests/breakpoints/Makefile @@ -16,8 +16,9 @@ else echo "Not an x86 target, can't build breakpoints selftests" endif -run_tests: - @./breakpoint_test || echo "breakpoints selftests: [FAIL]" +TEST_PROGS := breakpoint_test + +include ../lib.mk clean: rm -fr breakpoint_test diff --git a/tools/testing/selftests/cpu-hotplug/Makefile b/tools/testing/selftests/cpu-hotplug/Makefile index e9c28d8..15f0259 100644 --- a/tools/testing/selftests/cpu-hotplug/Makefile +++ b/tools/testing/selftests/cpu-hotplug/Makefile @@ -1,7 +1,8 @@ all: -run_tests: - @/bin/bash ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]" +TEST_PROGS := on-off-test.sh + +include ../lib.mk run_full_test: @/bin/bash ./on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" diff --git a/tools/testing/selftests/cpu-hotplug/on-off-test.sh b/tools/testing/selftests/cpu-hotplug/on-off-test.sh old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/efivarfs/Makefile b/tools/testing/selftests/efivarfs/Makefile index 29e8c6b..3052d0b 100644 --- a/tools/testing/selftests/efivarfs/Makefile +++ b/tools/testing/selftests/efivarfs/Makefile @@ -5,8 +5,9 @@ test_objs = open-unlink create-read all: $(test_objs) -run_tests: all - @/bin/bash ./efivarfs.sh || echo "efivarfs selftests: [FAIL]" +TEST_PROGS := efivarfs.sh + +include ../lib.mk clean: rm -f $(test_objs) diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 66dfc2c..a0098da 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -18,8 +18,9 @@ execveat.denatured: execveat %: %.c $(CC) $(CFLAGS) -o $@ $^ -run_tests: all - ./execveat +TEST_PROGS := execveat + +include ../lib.mk clean: rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx* diff --git a/tools/testing/selftests/firmware/Makefile b/tools/testing/selftests/firmware/Makefile index e23cce0..9bf8223 100644 --- a/tools/testing/selftests/firmware/Makefile +++ b/tools/testing/selftests/firmware/Makefile @@ -3,25 +3,9 @@ # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" all: -fw_filesystem: - @if /bin/sh ./fw_filesystem.sh ; then \ - echo "fw_filesystem: ok"; \ - else \ - echo "fw_filesystem: [FAIL]"; \ - exit 1; \ - fi +TEST_PROGS := fw_filesystem.sh fw_userhelper.sh -fw_userhelper: - @if /bin/sh ./fw_userhelper.sh ; then \ - echo "fw_userhelper: ok"; \ - else \ - echo "fw_userhelper: [FAIL]"; \ - exit 1; \ - fi - -run_tests: all fw_filesystem fw_userhelper +include ../lib.mk # Nothing to clean up. clean: - -.PHONY: all clean run_tests fw_filesystem fw_userhelper diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile index 76cc9f1..3467206 100644 --- a/tools/testing/selftests/ftrace/Makefile +++ b/tools/testing/selftests/ftrace/Makefile @@ -1,7 +1,8 @@ all: -run_tests: - @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]" +TEST_PROGS := ftracetest + +include ../lib.mk clean: rm -rf logs/* diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile index 74bbefd..3b6013d 100644 --- a/tools/testing/selftests/ipc/Makefile +++ b/tools/testing/selftests/ipc/Makefile @@ -18,8 +18,9 @@ else echo "Not an x86 target, can't build msgque selftest" endif -run_tests: all - ./msgque_test +TEST_PROGS := msgque_test + +include ../lib.mk clean: rm -fr ./msgque_test diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile index ff0eefd..0eecd18 100644 --- a/tools/testing/selftests/kcmp/Makefile +++ b/tools/testing/selftests/kcmp/Makefile @@ -3,8 +3,9 @@ CFLAGS += -I../../../../usr/include/ all: kcmp_test -run_tests: all - @./kcmp_test || echo "kcmp_test: [FAIL]" +TEST_PROGS := kcmp_test + +include ../lib.mk clean: $(RM) kcmp_test kcmp-test-file diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk new file mode 100644 index 0000000..b30c5a4 --- /dev/null +++ b/tools/testing/selftests/lib.mk @@ -0,0 +1,10 @@ +define RUN_TESTS + @for TEST in $(TEST_PROGS); do \ + (./$$TEST && echo "selftests: $$TEST [PASS]") || echo "selftests: $$TEST [FAIL]"; \ + done; +endef + +run_tests: all + $(RUN_TESTS) + +.PHONY: run_tests all clean diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index b80cd10..191dee9 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -5,9 +5,9 @@ CFLAGS += -I../../../../include/ all: gcc $(CFLAGS) memfd_test.c -o memfd_test -run_tests: all - gcc $(CFLAGS) memfd_test.c -o memfd_test - @./memfd_test || echo "memfd_test: [FAIL]" +TEST_PROGS := memfd_test + +include ../lib.mk build_fuse: gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile index d46b8d4..8f7dea6 100644 --- a/tools/testing/selftests/memory-hotplug/Makefile +++ b/tools/testing/selftests/memory-hotplug/Makefile @@ -1,7 +1,8 @@ all: -run_tests: - @/bin/bash ./on-off-test.sh -r 2 || echo "memory-hotplug selftests: [FAIL]" +include ../lib.mk + +override RUN_TESTS := ./on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" run_full_test: @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" diff --git a/tools/testing/selftests/memory-hotplug/on-off-test.sh b/tools/testing/selftests/memory-hotplug/on-off-test.sh old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile index 337d853..06931df 100644 --- a/tools/testing/selftests/mount/Makefile +++ b/tools/testing/selftests/mount/Makefile @@ -5,13 +5,9 @@ all: unprivileged-remount-test unprivileged-remount-test: unprivileged-remount-test.c gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test -# Allow specific tests to be selected. -test_unprivileged_remount: unprivileged-remount-test - @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi +include ../lib.mk -run_tests: all test_unprivileged_remount +override RUN_TESTS := if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi clean: rm -f unprivileged-remount-test - -.PHONY: all test_unprivileged_remount diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index 8056e2e..cbc300e 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile @@ -2,9 +2,12 @@ all: gcc -O2 mq_open_tests.c -o mq_open_tests -lrt gcc -O2 -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt -run_tests: - @./mq_open_tests /test1 || echo "mq_open_tests: [FAIL]" - @./mq_perf_tests || echo "mq_perf_tests: [FAIL]" +include ../lib.mk + +override define RUN_TESTS + @./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" + @./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" +endef clean: rm -f mq_open_tests mq_perf_tests diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 62f22cc..fa8187f 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -11,9 +11,9 @@ all: $(NET_PROGS) %: %.c $(CC) $(CFLAGS) -o $@ $^ -run_tests: all - @/bin/sh ./run_netsocktests || echo "sockettests: [FAIL]" - @/bin/sh ./run_afpackettests || echo "afpackettests: [FAIL]" - ./test_bpf.sh +TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh + +include ../lib.mk + clean: $(RM) $(NET_PROGS) diff --git a/tools/testing/selftests/net/run_afpackettests b/tools/testing/selftests/net/run_afpackettests old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/selftests/net/run_netsocktests old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/ptrace/Makefile b/tools/testing/selftests/ptrace/Makefile index 47ae2d3..453927f 100644 --- a/tools/testing/selftests/ptrace/Makefile +++ b/tools/testing/selftests/ptrace/Makefile @@ -6,5 +6,6 @@ all: peeksiginfo clean: rm -f peeksiginfo -run_tests: all - @./peeksiginfo || echo "peeksiginfo selftests: [FAIL]" +TEST_PROGS := peeksiginfo + +include ../lib.mk diff --git a/tools/testing/selftests/size/Makefile b/tools/testing/selftests/size/Makefile index 04dc25e..e4353d7 100644 --- a/tools/testing/selftests/size/Makefile +++ b/tools/testing/selftests/size/Makefile @@ -5,8 +5,9 @@ all: get_size get_size: get_size.c $(CC) -static -ffreestanding -nostartfiles -s $< -o $@ -run_tests: all - ./get_size +TEST_PROGS := get_size + +include ../lib.mk clean: $(RM) get_size diff --git a/tools/testing/selftests/sysctl/Makefile b/tools/testing/selftests/sysctl/Makefile index 0a92ada..c9660f5 100644 --- a/tools/testing/selftests/sysctl/Makefile +++ b/tools/testing/selftests/sysctl/Makefile @@ -4,16 +4,9 @@ # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". all: -# Allow specific tests to be selected. -test_num: - @/bin/sh ./run_numerictests +TEST_PROGS := run_numerictests run_stringtests -test_string: - @/bin/sh ./run_stringtests - -run_tests: all test_num test_string +include ../lib.mk # Nothing to clean up. clean: - -.PHONY: all run_tests clean test_num test_string diff --git a/tools/testing/selftests/sysctl/run_numerictests b/tools/testing/selftests/sysctl/run_numerictests old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/sysctl/run_stringtests b/tools/testing/selftests/sysctl/run_stringtests old mode 100644 new mode 100755 diff --git a/tools/testing/selftests/user/Makefile b/tools/testing/selftests/user/Makefile index 12c9d15..d401b63 100644 --- a/tools/testing/selftests/user/Makefile +++ b/tools/testing/selftests/user/Makefile @@ -3,5 +3,6 @@ # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" all: -run_tests: all - ./test_user_copy.sh +TEST_PROGS := test_user_copy.sh + +include ../lib.mk diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 077828c..90e5609 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -9,8 +9,9 @@ all: $(BINARIES) %: %.c $(CC) $(CFLAGS) -o $@ $^ -lrt -run_tests: all - @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1) +TEST_PROGS := run_vmtests + +include ../lib.mk clean: $(RM) $(BINARIES) diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests old mode 100644 new mode 100755 -- cgit v1.1 From 32dcfba6f8df667e4b915e0542b33ccbc8e76fa8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 11 Mar 2015 15:06:00 +1100 Subject: selftests: Add install target This adds make install support to selftests. The basic usage is: $ cd tools/testing/selftests $ make install That installs into tools/testing/selftests/install, which can then be copied where ever necessary. The install destination is also configurable using eg: $ INSTALL_PATH=/mnt/selftests make install The implementation uses two targets in the child makefiles. The first "install" is expected to install all files into $(INSTALL_PATH). The second, "emit_tests", is expected to emit the test instructions (ie. bash script) on stdout. Separating this from install means the child makefiles need no knowledge of the location of the test script. Signed-off-by: Michael Ellerman Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 33 +++++++++++++++++++++++++ tools/testing/selftests/efivarfs/Makefile | 1 + tools/testing/selftests/exec/Makefile | 3 +++ tools/testing/selftests/lib.mk | 23 ++++++++++++++++- tools/testing/selftests/memory-hotplug/Makefile | 2 ++ tools/testing/selftests/mount/Makefile | 2 ++ tools/testing/selftests/mqueue/Makefile | 7 ++++++ tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/sysctl/Makefile | 1 + tools/testing/selftests/vm/Makefile | 1 + 10 files changed, 73 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 4e51122..9af1df2 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -47,7 +47,40 @@ clean_hotplug: make -C $$TARGET clean; \ done; +INSTALL_PATH ?= install +INSTALL_PATH := $(abspath $(INSTALL_PATH)) +ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh + +install: +ifdef INSTALL_PATH + @# Ask all targets to install their files + mkdir -p $(INSTALL_PATH) + for TARGET in $(TARGETS); do \ + mkdir -p $(INSTALL_PATH)/$$TARGET ; \ + make -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ + done; + + @# Ask all targets to emit their test scripts + echo "#!/bin/bash" > $(ALL_SCRIPT) + echo "cd \$$(dirname \$$0)" >> $(ALL_SCRIPT) + echo "ROOT=\$$PWD" >> $(ALL_SCRIPT) + + for TARGET in $(TARGETS); do \ + echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ + echo "echo ========================================" >> $(ALL_SCRIPT); \ + echo "cd $$TARGET" >> $(ALL_SCRIPT); \ + make -s --no-print-directory -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ + echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ + done; + + chmod u+x $(ALL_SCRIPT) +else + $(error Error: set INSTALL_PATH to use install) +endif + clean: for TARGET in $(TARGETS); do \ make -C $$TARGET clean; \ done; + +.PHONY: install diff --git a/tools/testing/selftests/efivarfs/Makefile b/tools/testing/selftests/efivarfs/Makefile index 3052d0b..9ff04f1 100644 --- a/tools/testing/selftests/efivarfs/Makefile +++ b/tools/testing/selftests/efivarfs/Makefile @@ -6,6 +6,7 @@ test_objs = open-unlink create-read all: $(test_objs) TEST_PROGS := efivarfs.sh +TEST_FILES := $(test_objs) include ../lib.mk diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index a0098da..886cabe 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -19,8 +19,11 @@ execveat.denatured: execveat $(CC) $(CFLAGS) -o $@ $^ TEST_PROGS := execveat +TEST_FILES := $(DEPS) include ../lib.mk +override EMIT_TESTS := echo "mkdir -p subdir; (./execveat && echo \"selftests: execveat [PASS]\") || echo \"selftests: execveat [FAIL]\"" + clean: rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx* diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index b30c5a4..7bd3dab 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -7,4 +7,25 @@ endef run_tests: all $(RUN_TESTS) -.PHONY: run_tests all clean +define INSTALL_RULE + mkdir -p $(INSTALL_PATH) + install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_FILES) +endef + +install: all +ifdef INSTALL_PATH + $(INSTALL_RULE) +else + $(error Error: set INSTALL_PATH to use install) +endif + +define EMIT_TESTS + @for TEST in $(TEST_PROGS); do \ + echo "(./$$TEST && echo \"selftests: $$TEST [PASS]\") || echo \"selftests: $$TEST [FAIL]\""; \ + done; +endef + +emit_tests: + $(EMIT_TESTS) + +.PHONY: run_tests all clean install emit_tests diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile index 8f7dea6..598a1f6 100644 --- a/tools/testing/selftests/memory-hotplug/Makefile +++ b/tools/testing/selftests/memory-hotplug/Makefile @@ -2,7 +2,9 @@ all: include ../lib.mk +TEST_PROGS := on-off-test.sh override RUN_TESTS := ./on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" +override EMIT_TESTS := echo "$(RUN_TESTS)" run_full_test: @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile index 06931df..a5b367f 100644 --- a/tools/testing/selftests/mount/Makefile +++ b/tools/testing/selftests/mount/Makefile @@ -7,7 +7,9 @@ unprivileged-remount-test: unprivileged-remount-test.c include ../lib.mk +TEST_PROGS := unprivileged-remount-test override RUN_TESTS := if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi +override EMIT_TESTS := echo "$(RUN_TESTS)" clean: rm -f unprivileged-remount-test diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index cbc300e..6ca7261 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile @@ -9,5 +9,12 @@ override define RUN_TESTS @./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" endef +TEST_PROGS := mq_open_tests mq_perf_tests + +override define EMIT_TESTS + echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\"" + echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\"" +endef + clean: rm -f mq_open_tests mq_perf_tests diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index fa8187f..6ba2ac7 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -12,6 +12,7 @@ all: $(NET_PROGS) $(CC) $(CFLAGS) -o $@ $^ TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh +TEST_FILES := $(NET_PROGS) include ../lib.mk diff --git a/tools/testing/selftests/sysctl/Makefile b/tools/testing/selftests/sysctl/Makefile index c9660f5..b3c33e0 100644 --- a/tools/testing/selftests/sysctl/Makefile +++ b/tools/testing/selftests/sysctl/Makefile @@ -5,6 +5,7 @@ all: TEST_PROGS := run_numerictests run_stringtests +TEST_FILES := common_tests include ../lib.mk diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 90e5609..1a49761 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -10,6 +10,7 @@ all: $(BINARIES) $(CC) $(CFLAGS) -o $@ $^ -lrt TEST_PROGS := run_vmtests +TEST_FILES := $(BINARIES) include ../lib.mk -- cgit v1.1 From 1c0a7498c79443d4b72a0352dea70f27c5772b56 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 18 Mar 2015 08:51:53 -0700 Subject: kselftest/timers: Set default threadtest values to simplify execution scripts In order to keep the kselftest Makefiles simpler, set the threadtest default values to the ones used in standard run_tests Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/threadtest.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/timers/threadtest.c b/tools/testing/selftests/timers/threadtest.c index facd889..e632e11 100644 --- a/tools/testing/selftests/timers/threadtest.c +++ b/tools/testing/selftests/timers/threadtest.c @@ -126,11 +126,13 @@ void *independent_thread(void *arg) return NULL; } +#define DEFAULT_THREAD_COUNT 8 +#define DEFAULT_RUNTIME 30 int main(int argc, char **argv) { - int thread_count = 1, i; - time_t start, now, runtime = 60; + int thread_count, i; + time_t start, now, runtime; char buf[255]; pthread_t pth[MAX_THREADS]; int opt; @@ -138,6 +140,8 @@ int main(int argc, char **argv) int ret = 0; void *(*thread)(void *) = shared_thread; + thread_count = DEFAULT_THREAD_COUNT; + runtime = DEFAULT_RUNTIME; /* Process arguments */ while ((opt = getopt(argc, argv, "t:n:i")) != -1) { -- cgit v1.1 From 5744de542dd4b963c2975e6f70844ce2899864e4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 19 Mar 2015 11:20:40 +1100 Subject: selftests/timers: Use shared logic to run and install tests Change the timers Makefile to make use of shared run and install logic in lib.mk. Destructive tests are installed but not run by default. Add a new variable, TEST_PROGS_EXTENDED, which is a list of extra programs to install, but which are not run by the default run_tests logic. Signed-off-by: Michael Ellerman Signed-off-by: Shuah Khan --- tools/testing/selftests/lib.mk | 2 +- tools/testing/selftests/timers/Makefile | 27 ++++++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 7bd3dab..0baf7d3 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -9,7 +9,7 @@ run_tests: all define INSTALL_RULE mkdir -p $(INSTALL_PATH) - install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_FILES) + install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) endef install: all diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 9da3498..670aebd 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -2,24 +2,21 @@ CC = $(CROSS_COMPILE)gcc BUILD_FLAGS = -DKTEST CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) LDFLAGS += -lrt -lpthread -bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ - set-timer-lat threadtest mqueue-lat valid-adjtimex \ - alarmtimer-suspend change_skew skew_consistency clocksource-switch \ - leap-a-day leapcrash set-tai set-2038 - -all: ${bins} # these are all "safe" tests that don't modify # system time or require escalated privledges -run_tests: all - ./posix_timers - ./nanosleep - ./nsleep-lat - ./set-timer-lat - ./mqueue-lat - ./inconsistency-check - ./raw_skew - ./threadtest -t 30 -n 8 +TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ + inconsistency-check raw_skew threadtest + +TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \ + skew_consistency clocksource-switch leap-a-day \ + leapcrash set-tai set-2038 + +bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED) + +all: ${bins} + +include ../lib.mk # these tests require escalated privledges # and may modify the system time or trigger -- cgit v1.1 From 6faeeea44b84ce24fc6c1f1beb07ee5de9885dc8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 11 Mar 2015 15:06:01 +1100 Subject: selftests: Add install support for the powerpc tests The bulk of the selftests are actually below the powerpc sub directory. This adds support for installing them, when on a powerpc machine, or if ARCH and CROSS_COMPILE are set appropriately. This is a little more complicated because of the sub directory structure under powerpc, but much of the common logic in lib.mk is still used. The net effect of the patch is still a reduction in code. Signed-off-by: Michael Ellerman Signed-off-by: Shuah Khan --- tools/testing/selftests/powerpc/Makefile | 19 ++++++++- tools/testing/selftests/powerpc/copyloops/Makefile | 15 +++---- tools/testing/selftests/powerpc/mm/Makefile | 15 +++---- tools/testing/selftests/powerpc/pmu/Makefile | 48 ++++++++++++---------- tools/testing/selftests/powerpc/pmu/ebb/Makefile | 13 +++--- .../testing/selftests/powerpc/primitives/Makefile | 15 +++---- .../testing/selftests/powerpc/stringloops/Makefile | 15 +++---- tools/testing/selftests/powerpc/tm/Makefile | 15 +++---- 8 files changed, 73 insertions(+), 82 deletions(-) diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 1d5e7ad..22c4f8f 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -22,10 +22,25 @@ all: $(TARGETS) $(TARGETS): $(MAKE) -k -C $@ all -run_tests: all +include ../lib.mk + +override define RUN_TESTS @for TARGET in $(TARGETS); do \ $(MAKE) -C $$TARGET run_tests; \ done; +endef + +override define INSTALL_RULE + @for TARGET in $(TARGETS); do \ + $(MAKE) -C $$TARGET install; \ + done; +endef + +override define EMIT_TESTS + @for TARGET in $(TARGETS); do \ + $(MAKE) -s -C $$TARGET emit_tests; \ + done; +endef clean: @for TARGET in $(TARGETS); do \ @@ -36,4 +51,4 @@ clean: tags: find . -name '*.c' -o -name '*.h' | xargs ctags -.PHONY: all run_tests clean tags $(TARGETS) +.PHONY: tags $(TARGETS) diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile index 6f2d3be..c050235 100644 --- a/tools/testing/selftests/powerpc/copyloops/Makefile +++ b/tools/testing/selftests/powerpc/copyloops/Makefile @@ -6,24 +6,19 @@ CFLAGS += -D SELFTEST # Use our CFLAGS for the implicit .S rule ASFLAGS = $(CFLAGS) -PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 +TEST_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 EXTRA_SOURCES := validate.c ../harness.c -all: $(PROGS) +all: $(TEST_PROGS) copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 -$(PROGS): $(EXTRA_SOURCES) +$(TEST_PROGS): $(EXTRA_SOURCES) -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk clean: - rm -f $(PROGS) *.o - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) *.o diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index a14c538..41cc3ed 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile @@ -1,21 +1,16 @@ noarg: $(MAKE) -C ../ -PROGS := hugetlb_vs_thp_test subpage_prot +TEST_PROGS := hugetlb_vs_thp_test subpage_prot -all: $(PROGS) tempfile +all: $(TEST_PROGS) tempfile -$(PROGS): ../harness.c +$(TEST_PROGS): ../harness.c -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk tempfile: dd if=/dev/zero of=tempfile bs=64k count=1 clean: - rm -f $(PROGS) tempfile - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) tempfile diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index c9f4263..5a16117 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -1,38 +1,42 @@ noarg: $(MAKE) -C ../ -PROGS := count_instructions l3_bank_test per_event_excludes +TEST_PROGS := count_instructions l3_bank_test per_event_excludes EXTRA_SOURCES := ../harness.c event.c lib.c -SUB_TARGETS = ebb +all: $(TEST_PROGS) ebb -all: $(PROGS) $(SUB_TARGETS) - -$(PROGS): $(EXTRA_SOURCES) +$(TEST_PROGS): $(EXTRA_SOURCES) # loop.S can only be built 64-bit count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) $(CC) $(CFLAGS) -m64 -o $@ $^ -run_tests: all sub_run_tests - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk -clean: sub_clean - rm -f $(PROGS) loop.o +DEFAULT_RUN_TESTS := $(RUN_TESTS) +override define RUN_TESTS + $(DEFAULT_RUN_TESTS) + $(MAKE) -C ebb run_tests +endef -$(SUB_TARGETS): - $(MAKE) -k -C $@ all +DEFAULT_EMIT_TESTS := $(EMIT_TESTS) +override define EMIT_TESTS + $(DEFAULT_EMIT_TESTS) + $(MAKE) -s -C ebb emit_tests +endef -sub_run_tests: all - @for TARGET in $(SUB_TARGETS); do \ - $(MAKE) -C $$TARGET run_tests; \ - done; +DEFAULT_INSTALL := $(INSTALL_RULE) +override define INSTALL_RULE + $(DEFAULT_INSTALL_RULE) + $(MAKE) -C ebb install +endef -sub_clean: - @for TARGET in $(SUB_TARGETS); do \ - $(MAKE) -C $$TARGET clean; \ - done; +clean: + rm -f $(TEST_PROGS) loop.o + $(MAKE) -C ebb clean + +ebb: + $(MAKE) -k -C $@ all -.PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS) +.PHONY: all run_tests clean ebb diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index 3dc4332..5cdc9db 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile @@ -4,7 +4,7 @@ noarg: # The EBB handler is 64-bit code and everything links against it CFLAGS += -m64 -PROGS := reg_access_test event_attributes_test cycles_test \ +TEST_PROGS := reg_access_test event_attributes_test cycles_test \ cycles_with_freeze_test pmc56_overflow_test \ ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ @@ -16,18 +16,15 @@ PROGS := reg_access_test event_attributes_test cycles_test \ lost_exception_test no_handler_test \ cycles_with_mmcr2_test -all: $(PROGS) +all: $(TEST_PROGS) -$(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S +$(TEST_PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S instruction_count_test: ../loop.S lost_exception_test: ../lib.c -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../../lib.mk clean: - rm -f $(PROGS) + rm -f $(TEST_PROGS) diff --git a/tools/testing/selftests/powerpc/primitives/Makefile b/tools/testing/selftests/powerpc/primitives/Makefile index ea737ca..b68c622 100644 --- a/tools/testing/selftests/powerpc/primitives/Makefile +++ b/tools/testing/selftests/powerpc/primitives/Makefile @@ -1,17 +1,12 @@ CFLAGS += -I$(CURDIR) -PROGS := load_unaligned_zeropad +TEST_PROGS := load_unaligned_zeropad -all: $(PROGS) +all: $(TEST_PROGS) -$(PROGS): ../harness.c +$(TEST_PROGS): ../harness.c -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk clean: - rm -f $(PROGS) *.o - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) *.o diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile index 506d773..2a728f4 100644 --- a/tools/testing/selftests/powerpc/stringloops/Makefile +++ b/tools/testing/selftests/powerpc/stringloops/Makefile @@ -2,19 +2,14 @@ CFLAGS += -m64 CFLAGS += -I$(CURDIR) -PROGS := memcmp +TEST_PROGS := memcmp EXTRA_SOURCES := memcmp_64.S ../harness.c -all: $(PROGS) +all: $(TEST_PROGS) -$(PROGS): $(EXTRA_SOURCES) +$(TEST_PROGS): $(EXTRA_SOURCES) -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk clean: - rm -f $(PROGS) *.o - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) *.o diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile index 2cede23..34f2ec63 100644 --- a/tools/testing/selftests/powerpc/tm/Makefile +++ b/tools/testing/selftests/powerpc/tm/Makefile @@ -1,15 +1,10 @@ -PROGS := tm-resched-dscr +TEST_PROGS := tm-resched-dscr -all: $(PROGS) +all: $(TEST_PROGS) -$(PROGS): ../harness.c +$(TEST_PROGS): ../harness.c -run_tests: all - @-for PROG in $(PROGS); do \ - ./$$PROG; \ - done; +include ../../lib.mk clean: - rm -f $(PROGS) *.o - -.PHONY: all run_tests clean + rm -f $(TEST_PROGS) *.o -- cgit v1.1 From 84f887bfb930e7fbc01c060edd68c7cc6e2b824b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 4 Mar 2015 21:41:31 +1100 Subject: selftests: Set CC using CROSS_COMPILE once in lib.mk This avoids repeating the logic in every Makefile. We mimic the top-level Makefile and use $(CROSS_COMPILE)gcc. Signed-off-by: Michael Ellerman Signed-off-by: Shuah Khan --- tools/testing/selftests/efivarfs/Makefile | 1 - tools/testing/selftests/exec/Makefile | 1 - tools/testing/selftests/kcmp/Makefile | 1 - tools/testing/selftests/lib.mk | 4 ++++ tools/testing/selftests/net/Makefile | 1 - tools/testing/selftests/powerpc/Makefile | 3 +-- tools/testing/selftests/size/Makefile | 2 -- tools/testing/selftests/vm/Makefile | 1 - 8 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/efivarfs/Makefile b/tools/testing/selftests/efivarfs/Makefile index 9ff04f1..736c3dd 100644 --- a/tools/testing/selftests/efivarfs/Makefile +++ b/tools/testing/selftests/efivarfs/Makefile @@ -1,4 +1,3 @@ -CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall test_objs = open-unlink create-read diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 886cabe..4edb7d0 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -1,4 +1,3 @@ -CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall BINARIES = execveat DEPS = execveat.symlink execveat.denatured script subdir diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile index 0eecd18..2ae7450 100644 --- a/tools/testing/selftests/kcmp/Makefile +++ b/tools/testing/selftests/kcmp/Makefile @@ -1,4 +1,3 @@ -CC := $(CROSS_COMPILE)$(CC) CFLAGS += -I../../../../usr/include/ all: kcmp_test diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 0baf7d3..2194155 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -1,3 +1,7 @@ +# This mimics the top-level Makefile. We do it explicitly here so that this +# Makefile can operate with or without the kbuild infrastructure. +CC := $(CROSS_COMPILE)gcc + define RUN_TESTS @for TEST in $(TEST_PROGS); do \ (./$$TEST && echo "selftests: $$TEST [PASS]") || echo "selftests: $$TEST [FAIL]"; \ diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 6ba2ac7..fac4782 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -1,6 +1,5 @@ # Makefile for net selftests -CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall -O2 -g CFLAGS += -I../../../../usr/include/ diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 22c4f8f..2958fe9a 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -8,10 +8,9 @@ ifeq ($(ARCH),powerpc) GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") -CC := $(CROSS_COMPILE)$(CC) CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) -export CC CFLAGS +export CFLAGS TARGETS = pmu copyloops mm tm primitives stringloops diff --git a/tools/testing/selftests/size/Makefile b/tools/testing/selftests/size/Makefile index e4353d7..bbd0b53 100644 --- a/tools/testing/selftests/size/Makefile +++ b/tools/testing/selftests/size/Makefile @@ -1,5 +1,3 @@ -CC = $(CROSS_COMPILE)gcc - all: get_size get_size: get_size.c diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 1a49761..a5ce953 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -1,6 +1,5 @@ # Makefile for vm selftests -CC = $(CROSS_COMPILE)gcc CFLAGS = -Wall BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest BINARIES += transhuge-stress -- cgit v1.1 From 219794052f753fae54def9ba6758b31447b0244d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 18 Mar 2015 15:19:50 -0600 Subject: selftests: Add kselftest install tool kselftest_install.sh tool installs selftests in default location which is tools/testing/selftests/kselftest or an user specified location. This tool invokes back-end selftests install target with the install location. Usage: cd tools/testing/selftests ./kselftest_install.sh [ install_dir ] Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest_install.sh | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100755 tools/testing/selftests/kselftest_install.sh diff --git a/tools/testing/selftests/kselftest_install.sh b/tools/testing/selftests/kselftest_install.sh new file mode 100755 index 0000000..1555fbd --- /dev/null +++ b/tools/testing/selftests/kselftest_install.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Kselftest Install +# Install kselftest tests +# Author: Shuah Khan +# Copyright (C) 2015 Samsung Electronics Co., Ltd. + +# This software may be freely redistributed under the terms of the GNU +# General Public License (GPLv2). + +install_loc=`pwd` + +main() +{ + if [ $(basename $install_loc) != "selftests" ]; then + echo "$0: Please run it in selftests directory ..." + exit 1; + fi + if [ "$#" -eq 0 ]; then + echo "$0: Installing in default location - $install_loc ..." + elif [ ! -d "$1" ]; then + echo "$0: $1 doesn't exist!!" + exit 1; + else + install_loc=$1 + echo "$0: Installing in specified location - $install_loc ..." + fi + + install_dir=$install_loc/kselftest + +# Create install directory + mkdir -p $install_dir +# Build tests + INSTALL_PATH=$install_dir make install +} + +main "$@" -- cgit v1.1 From f901caaf8e45c7917029ec9197622f0167ea2d40 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 18 Mar 2015 15:38:08 -0600 Subject: selftests: Add tool to generate kselftest tar archive gen_kselftest_tar.sh tool generates kselftest tar archive. This tool supports uncompressed tar, gz, bz, and xz compression formats and the default compression format is gzip. This tool runs kselftest install tool as its back-end. Usage: cd tools/testing/selftests ./gen_kselftest_tar [ tar | targz | tarbz2 | tarxz ] Signed-off-by: Shuah Khan --- tools/testing/selftests/gen_kselftest_tar.sh | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 tools/testing/selftests/gen_kselftest_tar.sh diff --git a/tools/testing/selftests/gen_kselftest_tar.sh b/tools/testing/selftests/gen_kselftest_tar.sh new file mode 100755 index 0000000..17d5bd0 --- /dev/null +++ b/tools/testing/selftests/gen_kselftest_tar.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# +# gen_kselftest_tar +# Generate kselftest tarball +# Author: Shuah Khan +# Copyright (C) 2015 Samsung Electronics Co., Ltd. + +# This software may be freely redistributed under the terms of the GNU +# General Public License (GPLv2). + +# main +main() +{ + if [ "$#" -eq 0 ]; then + echo "$0: Generating default compression gzip" + copts="cvzf" + ext=".tar.gz" + else + case "$1" in + tar) + copts="cvf" + ext=".tar" + ;; + targz) + copts="cvzf" + ext=".tar.gz" + ;; + tarbz2) + copts="cvjf" + ext=".tar.bz2" + ;; + tarxz) + copts="cvJf" + ext=".tar.xz" + ;; + *) + echo "Unknown tarball format $1" + exit 1 + ;; + esac + fi + + install_dir=./kselftest + +# Run install using INSTALL_KSFT_PATH override to generate install +# directory +./kselftest_install.sh +tar $copts kselftest${ext} $install_dir +echo "Kselftest archive kselftest${ext} created!" + +# clean up install directory +rm -rf kselftest +} + +main "$@" -- cgit v1.1 From 4a5fd81507eaea556e533e9ebc8a3cf31fe159d1 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 23 Mar 2015 16:32:09 -0400 Subject: Documentation, split up rtc.txt into documentation and test file This patch splits rtc.txt into two separate files, one for the documentation itself, and the other for the rtctest.c file. The rtctest file is moved into the kernel tools/testing/selftests/timers directory. This will make automated testing easier. Note that the only difference in the rtc.txt file is that the location of the rtctest.c file has changed. Signed-off-by: Prarit Bhargava Acked-by: Jonathan Corbet Acked-by: John Stultz Cc: corbet@lwn.net Cc: rtc-linux@googlegroups.com Cc: linux-doc@vger.kernel.org Cc: a.zummo@towertech.it Cc: prarit@redhat.com Cc: john.stultz@linaro.org Cc: shuahkh@osg.samsung.com Signed-off-by: Shuah Khan --- Documentation/rtc.txt | 264 +------------------------------ tools/testing/selftests/timers/Makefile | 2 +- tools/testing/selftests/timers/rtctest.c | 258 ++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+), 264 deletions(-) create mode 100644 tools/testing/selftests/timers/rtctest.c diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt index 596b60c..8446f1e 100644 --- a/Documentation/rtc.txt +++ b/Documentation/rtc.txt @@ -204,266 +204,4 @@ Some common examples: * RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code. -If all else fails, check out the rtc-test.c driver! - - --------------------- 8< ---------------- 8< ----------------------------- - -/* - * Real Time Clock Driver Test/Example Program - * - * Compile with: - * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest - * - * Copyright (C) 1996, Paul Gortmaker. - * - * Released under the GNU General Public License, version 2, - * included herein by reference. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * This expects the new RTC class driver framework, working with - * clocks that will often not be clones of what the PC-AT had. - * Use the command line to specify another RTC if you need one. - */ -static const char default_rtc[] = "/dev/rtc0"; - - -int main(int argc, char **argv) -{ - int i, fd, retval, irqcount = 0; - unsigned long tmp, data; - struct rtc_time rtc_tm; - const char *rtc = default_rtc; - - switch (argc) { - case 2: - rtc = argv[1]; - /* FALLTHROUGH */ - case 1: - break; - default: - fprintf(stderr, "usage: rtctest [rtcdev]\n"); - return 1; - } - - fd = open(rtc, O_RDONLY); - - if (fd == -1) { - perror(rtc); - exit(errno); - } - - fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); - - /* Turn on update interrupts (one per second) */ - retval = ioctl(fd, RTC_UIE_ON, 0); - if (retval == -1) { - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Update IRQs not supported.\n"); - goto test_READ; - } - perror("RTC_UIE_ON ioctl"); - exit(errno); - } - - fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", - rtc); - fflush(stderr); - for (i=1; i<6; i++) { - /* This read will block */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } - - fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); - fflush(stderr); - for (i=1; i<6; i++) { - struct timeval tv = {5, 0}; /* 5 second timeout on select */ - fd_set readfds; - - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - /* The select will wait until an RTC interrupt happens. */ - retval = select(fd+1, &readfds, NULL, NULL, &tv); - if (retval == -1) { - perror("select"); - exit(errno); - } - /* This read won't block unlike the select-less case above. */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } - - /* Turn off update interrupts */ - retval = ioctl(fd, RTC_UIE_OFF, 0); - if (retval == -1) { - perror("RTC_UIE_OFF ioctl"); - exit(errno); - } - -test_READ: - /* Read the RTC time/date */ - retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); - if (retval == -1) { - perror("RTC_RD_TIME ioctl"); - exit(errno); - } - - fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", - rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); - - /* Set the alarm to 5 sec in the future, and check for rollover */ - rtc_tm.tm_sec += 5; - if (rtc_tm.tm_sec >= 60) { - rtc_tm.tm_sec %= 60; - rtc_tm.tm_min++; - } - if (rtc_tm.tm_min == 60) { - rtc_tm.tm_min = 0; - rtc_tm.tm_hour++; - } - if (rtc_tm.tm_hour == 24) - rtc_tm.tm_hour = 0; - - retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); - if (retval == -1) { - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Alarm IRQs not supported.\n"); - goto test_PIE; - } - perror("RTC_ALM_SET ioctl"); - exit(errno); - } - - /* Read the current alarm settings */ - retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); - if (retval == -1) { - perror("RTC_ALM_READ ioctl"); - exit(errno); - } - - fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); - - /* Enable alarm interrupts */ - retval = ioctl(fd, RTC_AIE_ON, 0); - if (retval == -1) { - perror("RTC_AIE_ON ioctl"); - exit(errno); - } - - fprintf(stderr, "Waiting 5 seconds for alarm..."); - fflush(stderr); - /* This blocks until the alarm ring causes an interrupt */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - irqcount++; - fprintf(stderr, " okay. Alarm rang.\n"); - - /* Disable alarm interrupts */ - retval = ioctl(fd, RTC_AIE_OFF, 0); - if (retval == -1) { - perror("RTC_AIE_OFF ioctl"); - exit(errno); - } - -test_PIE: - /* Read periodic IRQ rate */ - retval = ioctl(fd, RTC_IRQP_READ, &tmp); - if (retval == -1) { - /* not all RTCs support periodic IRQs */ - if (errno == ENOTTY) { - fprintf(stderr, "\nNo periodic IRQ support\n"); - goto done; - } - perror("RTC_IRQP_READ ioctl"); - exit(errno); - } - fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); - - fprintf(stderr, "Counting 20 interrupts at:"); - fflush(stderr); - - /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ - for (tmp=2; tmp<=64; tmp*=2) { - - retval = ioctl(fd, RTC_IRQP_SET, tmp); - if (retval == -1) { - /* not all RTCs can change their periodic IRQ rate */ - if (errno == ENOTTY) { - fprintf(stderr, - "\n...Periodic IRQ rate is fixed\n"); - goto done; - } - perror("RTC_IRQP_SET ioctl"); - exit(errno); - } - - fprintf(stderr, "\n%ldHz:\t", tmp); - fflush(stderr); - - /* Enable periodic interrupts */ - retval = ioctl(fd, RTC_PIE_ON, 0); - if (retval == -1) { - perror("RTC_PIE_ON ioctl"); - exit(errno); - } - - for (i=1; i<21; i++) { - /* This blocks */ - retval = read(fd, &data, sizeof(unsigned long)); - if (retval == -1) { - perror("read"); - exit(errno); - } - fprintf(stderr, " %d",i); - fflush(stderr); - irqcount++; - } - - /* Disable periodic interrupts */ - retval = ioctl(fd, RTC_PIE_OFF, 0); - if (retval == -1) { - perror("RTC_PIE_OFF ioctl"); - exit(errno); - } - } - -done: - fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); - - close(fd); - - return 0; -} +If all else fails, check out the tools/testing/selftests/timers/rtctest.c test! diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 670aebd..89a3f44 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -6,7 +6,7 @@ LDFLAGS += -lrt -lpthread # these are all "safe" tests that don't modify # system time or require escalated privledges TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ - inconsistency-check raw_skew threadtest + inconsistency-check raw_skew threadtest rtctest TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \ skew_consistency clocksource-switch leap-a-day \ diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c new file mode 100644 index 0000000..1e06f46 --- /dev/null +++ b/tools/testing/selftests/timers/rtctest.c @@ -0,0 +1,258 @@ +/* + * Real Time Clock Driver Test/Example Program + * + * Compile with: + * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest + * + * Copyright (C) 1996, Paul Gortmaker. + * + * Released under the GNU General Public License, version 2, + * included herein by reference. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This expects the new RTC class driver framework, working with + * clocks that will often not be clones of what the PC-AT had. + * Use the command line to specify another RTC if you need one. + */ +static const char default_rtc[] = "/dev/rtc0"; + + +int main(int argc, char **argv) +{ + int i, fd, retval, irqcount = 0; + unsigned long tmp, data; + struct rtc_time rtc_tm; + const char *rtc = default_rtc; + + switch (argc) { + case 2: + rtc = argv[1]; + /* FALLTHROUGH */ + case 1: + break; + default: + fprintf(stderr, "usage: rtctest [rtcdev]\n"); + return 1; + } + + fd = open(rtc, O_RDONLY); + + if (fd == -1) { + perror(rtc); + exit(errno); + } + + fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); + + /* Turn on update interrupts (one per second) */ + retval = ioctl(fd, RTC_UIE_ON, 0); + if (retval == -1) { + if (errno == ENOTTY) { + fprintf(stderr, + "\n...Update IRQs not supported.\n"); + goto test_READ; + } + perror("RTC_UIE_ON ioctl"); + exit(errno); + } + + fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", + rtc); + fflush(stderr); + for (i=1; i<6; i++) { + /* This read will block */ + retval = read(fd, &data, sizeof(unsigned long)); + if (retval == -1) { + perror("read"); + exit(errno); + } + fprintf(stderr, " %d",i); + fflush(stderr); + irqcount++; + } + + fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); + fflush(stderr); + for (i=1; i<6; i++) { + struct timeval tv = {5, 0}; /* 5 second timeout on select */ + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + /* The select will wait until an RTC interrupt happens. */ + retval = select(fd+1, &readfds, NULL, NULL, &tv); + if (retval == -1) { + perror("select"); + exit(errno); + } + /* This read won't block unlike the select-less case above. */ + retval = read(fd, &data, sizeof(unsigned long)); + if (retval == -1) { + perror("read"); + exit(errno); + } + fprintf(stderr, " %d",i); + fflush(stderr); + irqcount++; + } + + /* Turn off update interrupts */ + retval = ioctl(fd, RTC_UIE_OFF, 0); + if (retval == -1) { + perror("RTC_UIE_OFF ioctl"); + exit(errno); + } + +test_READ: + /* Read the RTC time/date */ + retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); + if (retval == -1) { + perror("RTC_RD_TIME ioctl"); + exit(errno); + } + + fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); + + /* Set the alarm to 5 sec in the future, and check for rollover */ + rtc_tm.tm_sec += 5; + if (rtc_tm.tm_sec >= 60) { + rtc_tm.tm_sec %= 60; + rtc_tm.tm_min++; + } + if (rtc_tm.tm_min == 60) { + rtc_tm.tm_min = 0; + rtc_tm.tm_hour++; + } + if (rtc_tm.tm_hour == 24) + rtc_tm.tm_hour = 0; + + retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); + if (retval == -1) { + if (errno == ENOTTY) { + fprintf(stderr, + "\n...Alarm IRQs not supported.\n"); + goto test_PIE; + } + perror("RTC_ALM_SET ioctl"); + exit(errno); + } + + /* Read the current alarm settings */ + retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); + if (retval == -1) { + perror("RTC_ALM_READ ioctl"); + exit(errno); + } + + fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); + + /* Enable alarm interrupts */ + retval = ioctl(fd, RTC_AIE_ON, 0); + if (retval == -1) { + perror("RTC_AIE_ON ioctl"); + exit(errno); + } + + fprintf(stderr, "Waiting 5 seconds for alarm..."); + fflush(stderr); + /* This blocks until the alarm ring causes an interrupt */ + retval = read(fd, &data, sizeof(unsigned long)); + if (retval == -1) { + perror("read"); + exit(errno); + } + irqcount++; + fprintf(stderr, " okay. Alarm rang.\n"); + + /* Disable alarm interrupts */ + retval = ioctl(fd, RTC_AIE_OFF, 0); + if (retval == -1) { + perror("RTC_AIE_OFF ioctl"); + exit(errno); + } + +test_PIE: + /* Read periodic IRQ rate */ + retval = ioctl(fd, RTC_IRQP_READ, &tmp); + if (retval == -1) { + /* not all RTCs support periodic IRQs */ + if (errno == ENOTTY) { + fprintf(stderr, "\nNo periodic IRQ support\n"); + goto done; + } + perror("RTC_IRQP_READ ioctl"); + exit(errno); + } + fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); + + fprintf(stderr, "Counting 20 interrupts at:"); + fflush(stderr); + + /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ + for (tmp=2; tmp<=64; tmp*=2) { + + retval = ioctl(fd, RTC_IRQP_SET, tmp); + if (retval == -1) { + /* not all RTCs can change their periodic IRQ rate */ + if (errno == ENOTTY) { + fprintf(stderr, + "\n...Periodic IRQ rate is fixed\n"); + goto done; + } + perror("RTC_IRQP_SET ioctl"); + exit(errno); + } + + fprintf(stderr, "\n%ldHz:\t", tmp); + fflush(stderr); + + /* Enable periodic interrupts */ + retval = ioctl(fd, RTC_PIE_ON, 0); + if (retval == -1) { + perror("RTC_PIE_ON ioctl"); + exit(errno); + } + + for (i=1; i<21; i++) { + /* This blocks */ + retval = read(fd, &data, sizeof(unsigned long)); + if (retval == -1) { + perror("read"); + exit(errno); + } + fprintf(stderr, " %d",i); + fflush(stderr); + irqcount++; + } + + /* Disable periodic interrupts */ + retval = ioctl(fd, RTC_PIE_OFF, 0); + if (retval == -1) { + perror("RTC_PIE_OFF ioctl"); + exit(errno); + } + } + +done: + fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); + + close(fd); + + return 0; +} -- cgit v1.1 From 0b63accf87225b5eb7e52814c374cf02d733d4bb Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 18 Mar 2015 15:46:33 -0400 Subject: tools, update rtctest.c to verify passage of time rtctest.c checks to see if PIE is functioning by testing if 20 interrupts occur at rates from 2HZ to 64HZ. While this check is good, it does not check to see if the correct amount of time has actually passed. This misses situations where the RTC may be operating at a higher or lower frequency than expected. This patch introduces a simple check to verify if the time passed is less than 10% of what was programmed into the RTC. Signed-off-by: Prarit Bhargava Acked-by: John Stultz Cc: corbet@lwn.net Cc: rtc-linux@googlegroups.com Cc: linux-doc@vger.kernel.org Cc: a.zummo@towertech.it Cc: prarit@redhat.com Cc: john.stultz@linaro.org Cc: shuahkh@osg.samsung.com Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/rtctest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c index 1e06f46..d80ae85 100644 --- a/tools/testing/selftests/timers/rtctest.c +++ b/tools/testing/selftests/timers/rtctest.c @@ -36,6 +36,7 @@ int main(int argc, char **argv) unsigned long tmp, data; struct rtc_time rtc_tm; const char *rtc = default_rtc; + struct timeval start, end, diff; switch (argc) { case 2: @@ -230,12 +231,24 @@ test_PIE: } for (i=1; i<21; i++) { + gettimeofday(&start, NULL); /* This blocks */ retval = read(fd, &data, sizeof(unsigned long)); if (retval == -1) { perror("read"); exit(errno); } + gettimeofday(&end, NULL); + timersub(&end, &start, &diff); + if (diff.tv_sec > 0 || + diff.tv_usec > ((1000000L / tmp) * 1.10)) { + fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n", + diff.tv_sec, diff.tv_usec, + (1000000L / tmp)); + fflush(stdout); + exit(-1); + } + fprintf(stderr, " %d",i); fflush(stderr); irqcount++; -- cgit v1.1 From a05ffdce7155769ea5ac3409e1490fb9116dbaed Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 30 Mar 2015 16:21:40 +1100 Subject: ftracetest: Cope properly with stack tracer not being enabled If the stack tracer (CONFIG_STACK_TRACER) is disabled, the fgraph-filter-stack test blows chunks: [8] ftrace - function graph filters with stack tracer [FAIL] + reset_tracer + echo nop ./ftracetest: 19: /home/michael/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc: cannot create /proc/sys/kernel/stack_tracer_enabled: Directory nonexistent Fix it by checking if the proc file exists before echoing to it. With the patch applied it fails correctly with: [8] ftrace - function graph filters with stack tracer [UNSUPPORTED] Signed-off-by: Michael Ellerman Acked-by: Steven Rostedt Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc index c15e018..3b1cf20 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc @@ -16,7 +16,9 @@ fi do_reset() { reset_tracer - echo 0 > /proc/sys/kernel/stack_tracer_enabled + if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then + echo 0 > /proc/sys/kernel/stack_tracer_enabled + fi enable_tracing clear_trace echo > set_ftrace_filter -- cgit v1.1 From 44164c4ba98c3dd3560d929ba66da51b5170ff1c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 30 Mar 2015 16:21:00 +1100 Subject: ftracetest: Convert exit -1 to exit $FAIL POSIX says that exit takes an unsigned integer between 0 and 255, so using -1 doesn't work on POSIX shells. There is already a well-defined failure code, $FAIL (1), so use that. Signed-off-by: Michael Ellerman Acked-by: Steven Rostedt Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/00basic/basic4.tc | 2 +- tools/testing/selftests/ftrace/test.d/event/event-enable.tc | 2 +- tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc | 2 +- tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc | 2 +- tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc | 2 +- tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc | 2 +- tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc index fd9c49a..aa51f6c 100644 --- a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc +++ b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc @@ -2,4 +2,4 @@ # description: Basic event tracing check test -f available_events -a -f set_event -a -d events # check scheduler events are available -grep -q sched available_events && exit 0 || exit -1 \ No newline at end of file +grep -q sched available_events && exit 0 || exit $FAIL diff --git a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc index 668616d..dbddb78 100644 --- a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc @@ -9,7 +9,7 @@ do_reset() { fail() { #msg do_reset echo $1 - exit -1 + exit $FAIL } if [ ! -f set_event -o ! -d events/sched ]; then diff --git a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc index 655c415..ef9b95d 100644 --- a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc @@ -9,7 +9,7 @@ do_reset() { fail() { #msg do_reset echo $1 - exit -1 + exit $FAIL } if [ ! -f set_event -o ! -d events/sched ]; then diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc index 4808457..af8cf01 100644 --- a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc @@ -9,7 +9,7 @@ do_reset() { fail() { #msg do_reset echo $1 - exit -1 + exit $FAIL } if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc index 3b1cf20..15c2dba 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc @@ -27,7 +27,7 @@ do_reset() { fail() { # msg do_reset echo $1 - exit -1 + exit $FAIL } disable_tracing diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc index 6af5f63..0ab2189 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc @@ -17,7 +17,7 @@ do_reset() { fail() { # msg do_reset echo $1 - exit -1 + exit $FAIL } disable_tracing diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc index 2e719cb..7808336 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc @@ -31,7 +31,7 @@ fail() { # mesg reset_tracer echo > set_ftrace_filter echo $1 - exit -1 + exit $FAIL } echo "Testing function tracer with profiler:" -- cgit v1.1 From e48f284d63ece564f8aa19fbf5434b3458af8d3f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 25 Mar 2015 16:44:33 -0700 Subject: kselftests: timers: Reduce default runtime on inconsistency-check and set-timer-lat For the default run_timers target, the timers tests takes the majority of kselftests runtime. So this patch reduces the default runtime for inconsistentcy-check and set-timer-lat, which reduced the runtime almost in half. Before: 11m48.629s After: 6m47.723s Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/inconsistency-check.c | 2 +- tools/testing/selftests/timers/set-timer-lat.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c index 578e423..caf1bc9 100644 --- a/tools/testing/selftests/timers/inconsistency-check.c +++ b/tools/testing/selftests/timers/inconsistency-check.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) int clockid, opt; int userclock = CLOCK_REALTIME; int maxclocks = NR_CLOCKIDS; - int runtime = 30; + int runtime = 10; struct timespec ts; /* Process arguments */ diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 3ea2eff..2ed3267 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -58,7 +58,7 @@ static inline int ksft_exit_fail(void) #define NSEC_PER_SEC 1000000000ULL #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ -#define TIMER_SECS 3 +#define TIMER_SECS 1 int alarmcount; int clock_id; struct timespec start_time; -- cgit v1.1 From 8f3d7346435e8db1719f8cacb2de4fe87a68cb55 Mon Sep 17 00:00:00 2001 From: Zhang Zhen Date: Sat, 28 Mar 2015 09:51:13 +0800 Subject: selftests/mount: Make git ignore all binaries in mount test suite This patch includes the mount test binaries into the .gitignore file listing in their respective directories. This will make sure that git ignores all of these test binaries when displaying status. Signed-off-by: Zhang Zhen Signed-off-by: Shuah Khan --- tools/testing/selftests/mount/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 tools/testing/selftests/mount/.gitignore diff --git a/tools/testing/selftests/mount/.gitignore b/tools/testing/selftests/mount/.gitignore new file mode 100644 index 0000000..856ad41 --- /dev/null +++ b/tools/testing/selftests/mount/.gitignore @@ -0,0 +1 @@ +unprivileged-remount-test -- cgit v1.1 From cc16782169e5a7d523c82a45a24ead70d6e2275f Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 27 Mar 2015 10:03:48 -0600 Subject: selftests: change cpu on-off-test.sh name to be unique cpu and memory hotplug scripts use the same name. Change cpu on-off-test.sh to cpu-on-off-test.sh. Signed-off-by: Shuah Khan Acked-by: Greg Kroah-Hartman --- tools/testing/selftests/cpu-hotplug/Makefile | 4 +- .../selftests/cpu-hotplug/cpu-on-off-test.sh | 269 +++++++++++++++++++++ tools/testing/selftests/cpu-hotplug/on-off-test.sh | 269 --------------------- 3 files changed, 271 insertions(+), 271 deletions(-) create mode 100755 tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh delete mode 100755 tools/testing/selftests/cpu-hotplug/on-off-test.sh diff --git a/tools/testing/selftests/cpu-hotplug/Makefile b/tools/testing/selftests/cpu-hotplug/Makefile index 15f0259..fe1f991 100644 --- a/tools/testing/selftests/cpu-hotplug/Makefile +++ b/tools/testing/selftests/cpu-hotplug/Makefile @@ -1,10 +1,10 @@ all: -TEST_PROGS := on-off-test.sh +TEST_PROGS := cpu-on-off-test.sh include ../lib.mk run_full_test: - @/bin/bash ./on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" + @/bin/bash ./cpu-on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" clean: diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh new file mode 100755 index 0000000..98b1d65 --- /dev/null +++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh @@ -0,0 +1,269 @@ +#!/bin/bash + +SYSFS= + +prerequisite() +{ + msg="skip all tests:" + + if [ $UID != 0 ]; then + echo $msg must be run as root >&2 + exit 0 + fi + + taskset -p 01 $$ + + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` + + if [ ! -d "$SYSFS" ]; then + echo $msg sysfs is not mounted >&2 + exit 0 + fi + + if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then + echo $msg cpu hotplug is not supported >&2 + exit 0 + fi + + echo "CPU online/offline summary:" + online_cpus=`cat $SYSFS/devices/system/cpu/online` + online_max=${online_cpus##*-} + echo -e "\t Cpus in online state: $online_cpus" + + offline_cpus=`cat $SYSFS/devices/system/cpu/offline` + if [[ "a$offline_cpus" = "a" ]]; then + offline_cpus=0 + else + offline_max=${offline_cpus##*-} + fi + echo -e "\t Cpus in offline state: $offline_cpus" +} + +# +# list all hot-pluggable CPUs +# +hotpluggable_cpus() +{ + local state=${1:-.\*} + + for cpu in $SYSFS/devices/system/cpu/cpu*; do + if [ -f $cpu/online ] && grep -q $state $cpu/online; then + echo ${cpu##/*/cpu} + fi + done +} + +hotplaggable_offline_cpus() +{ + hotpluggable_cpus 0 +} + +hotpluggable_online_cpus() +{ + hotpluggable_cpus 1 +} + +cpu_is_online() +{ + grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online +} + +cpu_is_offline() +{ + grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online +} + +online_cpu() +{ + echo 1 > $SYSFS/devices/system/cpu/cpu$1/online +} + +offline_cpu() +{ + echo 0 > $SYSFS/devices/system/cpu/cpu$1/online +} + +online_cpu_expect_success() +{ + local cpu=$1 + + if ! online_cpu $cpu; then + echo $FUNCNAME $cpu: unexpected fail >&2 + elif ! cpu_is_online $cpu; then + echo $FUNCNAME $cpu: unexpected offline >&2 + fi +} + +online_cpu_expect_fail() +{ + local cpu=$1 + + if online_cpu $cpu 2> /dev/null; then + echo $FUNCNAME $cpu: unexpected success >&2 + elif ! cpu_is_offline $cpu; then + echo $FUNCNAME $cpu: unexpected online >&2 + fi +} + +offline_cpu_expect_success() +{ + local cpu=$1 + + if ! offline_cpu $cpu; then + echo $FUNCNAME $cpu: unexpected fail >&2 + elif ! cpu_is_offline $cpu; then + echo $FUNCNAME $cpu: unexpected offline >&2 + fi +} + +offline_cpu_expect_fail() +{ + local cpu=$1 + + if offline_cpu $cpu 2> /dev/null; then + echo $FUNCNAME $cpu: unexpected success >&2 + elif ! cpu_is_online $cpu; then + echo $FUNCNAME $cpu: unexpected offline >&2 + fi +} + +error=-12 +allcpus=0 +priority=0 +online_cpus=0 +online_max=0 +offline_cpus=0 +offline_max=0 + +while getopts e:ahp: opt; do + case $opt in + e) + error=$OPTARG + ;; + a) + allcpus=1 + ;; + h) + echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]" + echo -e "\t default offline one cpu" + echo -e "\t run with -a option to offline all cpus" + exit + ;; + p) + priority=$OPTARG + ;; + esac +done + +if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then + echo "error code must be -4095 <= errno < 0" >&2 + exit 1 +fi + +prerequisite + +# +# Safe test (default) - offline and online one cpu +# +if [ $allcpus -eq 0 ]; then + echo "Limited scope test: one hotplug cpu" + echo -e "\t (leaves cpu in the original state):" + echo -e "\t online to offline to online: cpu $online_max" + offline_cpu_expect_success $online_max + online_cpu_expect_success $online_max + + if [[ $offline_cpus -gt 0 ]]; then + echo -e "\t offline to online to offline: cpu $offline_max" + online_cpu_expect_success $offline_max + offline_cpu_expect_success $offline_max + fi + exit 0 +else + echo "Full scope test: all hotplug cpus" + echo -e "\t online all offline cpus" + echo -e "\t offline all online cpus" + echo -e "\t online all offline cpus" +fi + +# +# Online all hot-pluggable CPUs +# +for cpu in `hotplaggable_offline_cpus`; do + online_cpu_expect_success $cpu +done + +# +# Offline all hot-pluggable CPUs +# +for cpu in `hotpluggable_online_cpus`; do + offline_cpu_expect_success $cpu +done + +# +# Online all hot-pluggable CPUs again +# +for cpu in `hotplaggable_offline_cpus`; do + online_cpu_expect_success $cpu +done + +# +# Test with cpu notifier error injection +# + +DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` +NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu + +prerequisite_extra() +{ + msg="skip extra tests:" + + /sbin/modprobe -q -r cpu-notifier-error-inject + /sbin/modprobe -q cpu-notifier-error-inject priority=$priority + + if [ ! -d "$DEBUGFS" ]; then + echo $msg debugfs is not mounted >&2 + exit 0 + fi + + if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then + echo $msg cpu-notifier-error-inject module is not available >&2 + exit 0 + fi +} + +prerequisite_extra + +# +# Offline all hot-pluggable CPUs +# +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error +for cpu in `hotpluggable_online_cpus`; do + offline_cpu_expect_success $cpu +done + +# +# Test CPU hot-add error handling (offline => online) +# +echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error +for cpu in `hotplaggable_offline_cpus`; do + online_cpu_expect_fail $cpu +done + +# +# Online all hot-pluggable CPUs +# +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error +for cpu in `hotplaggable_offline_cpus`; do + online_cpu_expect_success $cpu +done + +# +# Test CPU hot-remove error handling (online => offline) +# +echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error +for cpu in `hotpluggable_online_cpus`; do + offline_cpu_expect_fail $cpu +done + +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error +/sbin/modprobe -q -r cpu-notifier-error-inject diff --git a/tools/testing/selftests/cpu-hotplug/on-off-test.sh b/tools/testing/selftests/cpu-hotplug/on-off-test.sh deleted file mode 100755 index 98b1d65..0000000 --- a/tools/testing/selftests/cpu-hotplug/on-off-test.sh +++ /dev/null @@ -1,269 +0,0 @@ -#!/bin/bash - -SYSFS= - -prerequisite() -{ - msg="skip all tests:" - - if [ $UID != 0 ]; then - echo $msg must be run as root >&2 - exit 0 - fi - - taskset -p 01 $$ - - SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` - - if [ ! -d "$SYSFS" ]; then - echo $msg sysfs is not mounted >&2 - exit 0 - fi - - if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then - echo $msg cpu hotplug is not supported >&2 - exit 0 - fi - - echo "CPU online/offline summary:" - online_cpus=`cat $SYSFS/devices/system/cpu/online` - online_max=${online_cpus##*-} - echo -e "\t Cpus in online state: $online_cpus" - - offline_cpus=`cat $SYSFS/devices/system/cpu/offline` - if [[ "a$offline_cpus" = "a" ]]; then - offline_cpus=0 - else - offline_max=${offline_cpus##*-} - fi - echo -e "\t Cpus in offline state: $offline_cpus" -} - -# -# list all hot-pluggable CPUs -# -hotpluggable_cpus() -{ - local state=${1:-.\*} - - for cpu in $SYSFS/devices/system/cpu/cpu*; do - if [ -f $cpu/online ] && grep -q $state $cpu/online; then - echo ${cpu##/*/cpu} - fi - done -} - -hotplaggable_offline_cpus() -{ - hotpluggable_cpus 0 -} - -hotpluggable_online_cpus() -{ - hotpluggable_cpus 1 -} - -cpu_is_online() -{ - grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online -} - -cpu_is_offline() -{ - grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online -} - -online_cpu() -{ - echo 1 > $SYSFS/devices/system/cpu/cpu$1/online -} - -offline_cpu() -{ - echo 0 > $SYSFS/devices/system/cpu/cpu$1/online -} - -online_cpu_expect_success() -{ - local cpu=$1 - - if ! online_cpu $cpu; then - echo $FUNCNAME $cpu: unexpected fail >&2 - elif ! cpu_is_online $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -online_cpu_expect_fail() -{ - local cpu=$1 - - if online_cpu $cpu 2> /dev/null; then - echo $FUNCNAME $cpu: unexpected success >&2 - elif ! cpu_is_offline $cpu; then - echo $FUNCNAME $cpu: unexpected online >&2 - fi -} - -offline_cpu_expect_success() -{ - local cpu=$1 - - if ! offline_cpu $cpu; then - echo $FUNCNAME $cpu: unexpected fail >&2 - elif ! cpu_is_offline $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -offline_cpu_expect_fail() -{ - local cpu=$1 - - if offline_cpu $cpu 2> /dev/null; then - echo $FUNCNAME $cpu: unexpected success >&2 - elif ! cpu_is_online $cpu; then - echo $FUNCNAME $cpu: unexpected offline >&2 - fi -} - -error=-12 -allcpus=0 -priority=0 -online_cpus=0 -online_max=0 -offline_cpus=0 -offline_max=0 - -while getopts e:ahp: opt; do - case $opt in - e) - error=$OPTARG - ;; - a) - allcpus=1 - ;; - h) - echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]" - echo -e "\t default offline one cpu" - echo -e "\t run with -a option to offline all cpus" - exit - ;; - p) - priority=$OPTARG - ;; - esac -done - -if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then - echo "error code must be -4095 <= errno < 0" >&2 - exit 1 -fi - -prerequisite - -# -# Safe test (default) - offline and online one cpu -# -if [ $allcpus -eq 0 ]; then - echo "Limited scope test: one hotplug cpu" - echo -e "\t (leaves cpu in the original state):" - echo -e "\t online to offline to online: cpu $online_max" - offline_cpu_expect_success $online_max - online_cpu_expect_success $online_max - - if [[ $offline_cpus -gt 0 ]]; then - echo -e "\t offline to online to offline: cpu $offline_max" - online_cpu_expect_success $offline_max - offline_cpu_expect_success $offline_max - fi - exit 0 -else - echo "Full scope test: all hotplug cpus" - echo -e "\t online all offline cpus" - echo -e "\t offline all online cpus" - echo -e "\t online all offline cpus" -fi - -# -# Online all hot-pluggable CPUs -# -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Offline all hot-pluggable CPUs -# -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_success $cpu -done - -# -# Online all hot-pluggable CPUs again -# -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Test with cpu notifier error injection -# - -DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` -NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu - -prerequisite_extra() -{ - msg="skip extra tests:" - - /sbin/modprobe -q -r cpu-notifier-error-inject - /sbin/modprobe -q cpu-notifier-error-inject priority=$priority - - if [ ! -d "$DEBUGFS" ]; then - echo $msg debugfs is not mounted >&2 - exit 0 - fi - - if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then - echo $msg cpu-notifier-error-inject module is not available >&2 - exit 0 - fi -} - -prerequisite_extra - -# -# Offline all hot-pluggable CPUs -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_success $cpu -done - -# -# Test CPU hot-add error handling (offline => online) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_fail $cpu -done - -# -# Online all hot-pluggable CPUs -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error -for cpu in `hotplaggable_offline_cpus`; do - online_cpu_expect_success $cpu -done - -# -# Test CPU hot-remove error handling (online => offline) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -for cpu in `hotpluggable_online_cpus`; do - offline_cpu_expect_fail $cpu -done - -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error -/sbin/modprobe -q -r cpu-notifier-error-inject -- cgit v1.1 From 072264fee89633b676f656613efff7dd5cdbf88a Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 27 Mar 2015 10:07:33 -0600 Subject: selftests: Change memory on-off-test.sh name to be unique cpu and memory hotplug scripts use the same name. Change memory on-off-test.sh to mem-on-off-test.sh. Signed-off-by: Shuah Khan Acked-by: Greg Kroah-Hartman --- tools/testing/selftests/memory-hotplug/Makefile | 6 +- .../selftests/memory-hotplug/mem-on-off-test.sh | 238 +++++++++++++++++++++ .../selftests/memory-hotplug/on-off-test.sh | 238 --------------------- 3 files changed, 241 insertions(+), 241 deletions(-) create mode 100755 tools/testing/selftests/memory-hotplug/mem-on-off-test.sh delete mode 100755 tools/testing/selftests/memory-hotplug/on-off-test.sh diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile index 598a1f6..afb2624 100644 --- a/tools/testing/selftests/memory-hotplug/Makefile +++ b/tools/testing/selftests/memory-hotplug/Makefile @@ -2,11 +2,11 @@ all: include ../lib.mk -TEST_PROGS := on-off-test.sh -override RUN_TESTS := ./on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" +TEST_PROGS := mem-on-off-test.sh +override RUN_TESTS := ./mem-on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" override EMIT_TESTS := echo "$(RUN_TESTS)" run_full_test: - @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" + @/bin/bash ./mem-on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" clean: diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh new file mode 100755 index 0000000..6cddde0 --- /dev/null +++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh @@ -0,0 +1,238 @@ +#!/bin/bash + +SYSFS= + +prerequisite() +{ + msg="skip all tests:" + + if [ $UID != 0 ]; then + echo $msg must be run as root >&2 + exit 0 + fi + + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` + + if [ ! -d "$SYSFS" ]; then + echo $msg sysfs is not mounted >&2 + exit 0 + fi + + if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then + echo $msg memory hotplug is not supported >&2 + exit 0 + fi +} + +# +# list all hot-pluggable memory +# +hotpluggable_memory() +{ + local state=${1:-.\*} + + for memory in $SYSFS/devices/system/memory/memory*; do + if grep -q 1 $memory/removable && + grep -q $state $memory/state; then + echo ${memory##/*/memory} + fi + done +} + +hotplaggable_offline_memory() +{ + hotpluggable_memory offline +} + +hotpluggable_online_memory() +{ + hotpluggable_memory online +} + +memory_is_online() +{ + grep -q online $SYSFS/devices/system/memory/memory$1/state +} + +memory_is_offline() +{ + grep -q offline $SYSFS/devices/system/memory/memory$1/state +} + +online_memory() +{ + echo online > $SYSFS/devices/system/memory/memory$1/state +} + +offline_memory() +{ + echo offline > $SYSFS/devices/system/memory/memory$1/state +} + +online_memory_expect_success() +{ + local memory=$1 + + if ! online_memory $memory; then + echo $FUNCNAME $memory: unexpected fail >&2 + elif ! memory_is_online $memory; then + echo $FUNCNAME $memory: unexpected offline >&2 + fi +} + +online_memory_expect_fail() +{ + local memory=$1 + + if online_memory $memory 2> /dev/null; then + echo $FUNCNAME $memory: unexpected success >&2 + elif ! memory_is_offline $memory; then + echo $FUNCNAME $memory: unexpected online >&2 + fi +} + +offline_memory_expect_success() +{ + local memory=$1 + + if ! offline_memory $memory; then + echo $FUNCNAME $memory: unexpected fail >&2 + elif ! memory_is_offline $memory; then + echo $FUNCNAME $memory: unexpected offline >&2 + fi +} + +offline_memory_expect_fail() +{ + local memory=$1 + + if offline_memory $memory 2> /dev/null; then + echo $FUNCNAME $memory: unexpected success >&2 + elif ! memory_is_online $memory; then + echo $FUNCNAME $memory: unexpected offline >&2 + fi +} + +error=-12 +priority=0 +ratio=10 + +while getopts e:hp:r: opt; do + case $opt in + e) + error=$OPTARG + ;; + h) + echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" + exit + ;; + p) + priority=$OPTARG + ;; + r) + ratio=$OPTARG + ;; + esac +done + +if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then + echo "error code must be -4095 <= errno < 0" >&2 + exit 1 +fi + +prerequisite + +echo "Test scope: $ratio% hotplug memory" +echo -e "\t online all hotplug memory in offline state" +echo -e "\t offline $ratio% hotplug memory in online state" +echo -e "\t online all hotplug memory in offline state" + +# +# Online all hot-pluggable memory +# +for memory in `hotplaggable_offline_memory`; do + echo offline-online $memory + online_memory_expect_success $memory +done + +# +# Offline $ratio percent of hot-pluggable memory +# +for memory in `hotpluggable_online_memory`; do + if [ $((RANDOM % 100)) -lt $ratio ]; then + echo online-offline $memory + offline_memory_expect_success $memory + fi +done + +# +# Online all hot-pluggable memory again +# +for memory in `hotplaggable_offline_memory`; do + echo offline-online $memory + online_memory_expect_success $memory +done + +# +# Test with memory notifier error injection +# + +DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` +NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory + +prerequisite_extra() +{ + msg="skip extra tests:" + + /sbin/modprobe -q -r memory-notifier-error-inject + /sbin/modprobe -q memory-notifier-error-inject priority=$priority + + if [ ! -d "$DEBUGFS" ]; then + echo $msg debugfs is not mounted >&2 + exit 0 + fi + + if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then + echo $msg memory-notifier-error-inject module is not available >&2 + exit 0 + fi +} + +prerequisite_extra + +# +# Offline $ratio percent of hot-pluggable memory +# +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error +for memory in `hotpluggable_online_memory`; do + if [ $((RANDOM % 100)) -lt $ratio ]; then + offline_memory_expect_success $memory + fi +done + +# +# Test memory hot-add error handling (offline => online) +# +echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error +for memory in `hotplaggable_offline_memory`; do + online_memory_expect_fail $memory +done + +# +# Online all hot-pluggable memory +# +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error +for memory in `hotplaggable_offline_memory`; do + online_memory_expect_success $memory +done + +# +# Test memory hot-remove error handling (online => offline) +# +echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error +for memory in `hotpluggable_online_memory`; do + offline_memory_expect_fail $memory +done + +echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error +/sbin/modprobe -q -r memory-notifier-error-inject diff --git a/tools/testing/selftests/memory-hotplug/on-off-test.sh b/tools/testing/selftests/memory-hotplug/on-off-test.sh deleted file mode 100755 index 6cddde0..0000000 --- a/tools/testing/selftests/memory-hotplug/on-off-test.sh +++ /dev/null @@ -1,238 +0,0 @@ -#!/bin/bash - -SYSFS= - -prerequisite() -{ - msg="skip all tests:" - - if [ $UID != 0 ]; then - echo $msg must be run as root >&2 - exit 0 - fi - - SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` - - if [ ! -d "$SYSFS" ]; then - echo $msg sysfs is not mounted >&2 - exit 0 - fi - - if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then - echo $msg memory hotplug is not supported >&2 - exit 0 - fi -} - -# -# list all hot-pluggable memory -# -hotpluggable_memory() -{ - local state=${1:-.\*} - - for memory in $SYSFS/devices/system/memory/memory*; do - if grep -q 1 $memory/removable && - grep -q $state $memory/state; then - echo ${memory##/*/memory} - fi - done -} - -hotplaggable_offline_memory() -{ - hotpluggable_memory offline -} - -hotpluggable_online_memory() -{ - hotpluggable_memory online -} - -memory_is_online() -{ - grep -q online $SYSFS/devices/system/memory/memory$1/state -} - -memory_is_offline() -{ - grep -q offline $SYSFS/devices/system/memory/memory$1/state -} - -online_memory() -{ - echo online > $SYSFS/devices/system/memory/memory$1/state -} - -offline_memory() -{ - echo offline > $SYSFS/devices/system/memory/memory$1/state -} - -online_memory_expect_success() -{ - local memory=$1 - - if ! online_memory $memory; then - echo $FUNCNAME $memory: unexpected fail >&2 - elif ! memory_is_online $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -online_memory_expect_fail() -{ - local memory=$1 - - if online_memory $memory 2> /dev/null; then - echo $FUNCNAME $memory: unexpected success >&2 - elif ! memory_is_offline $memory; then - echo $FUNCNAME $memory: unexpected online >&2 - fi -} - -offline_memory_expect_success() -{ - local memory=$1 - - if ! offline_memory $memory; then - echo $FUNCNAME $memory: unexpected fail >&2 - elif ! memory_is_offline $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -offline_memory_expect_fail() -{ - local memory=$1 - - if offline_memory $memory 2> /dev/null; then - echo $FUNCNAME $memory: unexpected success >&2 - elif ! memory_is_online $memory; then - echo $FUNCNAME $memory: unexpected offline >&2 - fi -} - -error=-12 -priority=0 -ratio=10 - -while getopts e:hp:r: opt; do - case $opt in - e) - error=$OPTARG - ;; - h) - echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]" - exit - ;; - p) - priority=$OPTARG - ;; - r) - ratio=$OPTARG - ;; - esac -done - -if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then - echo "error code must be -4095 <= errno < 0" >&2 - exit 1 -fi - -prerequisite - -echo "Test scope: $ratio% hotplug memory" -echo -e "\t online all hotplug memory in offline state" -echo -e "\t offline $ratio% hotplug memory in online state" -echo -e "\t online all hotplug memory in offline state" - -# -# Online all hot-pluggable memory -# -for memory in `hotplaggable_offline_memory`; do - echo offline-online $memory - online_memory_expect_success $memory -done - -# -# Offline $ratio percent of hot-pluggable memory -# -for memory in `hotpluggable_online_memory`; do - if [ $((RANDOM % 100)) -lt $ratio ]; then - echo online-offline $memory - offline_memory_expect_success $memory - fi -done - -# -# Online all hot-pluggable memory again -# -for memory in `hotplaggable_offline_memory`; do - echo offline-online $memory - online_memory_expect_success $memory -done - -# -# Test with memory notifier error injection -# - -DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` -NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory - -prerequisite_extra() -{ - msg="skip extra tests:" - - /sbin/modprobe -q -r memory-notifier-error-inject - /sbin/modprobe -q memory-notifier-error-inject priority=$priority - - if [ ! -d "$DEBUGFS" ]; then - echo $msg debugfs is not mounted >&2 - exit 0 - fi - - if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then - echo $msg memory-notifier-error-inject module is not available >&2 - exit 0 - fi -} - -prerequisite_extra - -# -# Offline $ratio percent of hot-pluggable memory -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -for memory in `hotpluggable_online_memory`; do - if [ $((RANDOM % 100)) -lt $ratio ]; then - offline_memory_expect_success $memory - fi -done - -# -# Test memory hot-add error handling (offline => online) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_fail $memory -done - -# -# Online all hot-pluggable memory -# -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error -for memory in `hotplaggable_offline_memory`; do - online_memory_expect_success $memory -done - -# -# Test memory hot-remove error handling (online => offline) -# -echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -for memory in `hotpluggable_online_memory`; do - offline_memory_expect_fail $memory -done - -echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error -/sbin/modprobe -q -r memory-notifier-error-inject -- cgit v1.1 From 48fd77d1444a387435c3bbc773fa4e7ab6b6aca3 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 1 Apr 2015 20:43:39 -0700 Subject: kselftests: timers: Make set-timer-lat fail more gracefully for !CAP_WAKE_ALARM The set-timer-lat test fails when testing CLOCK_BOOTTIME_ALARM or CLOCK_REALTIME_ALARM when the user isn't running as root or with CAP_WAKE_ALARM. So this patch improves the error checking so we report the issue more clearly and continue rather then reporting a failure. Cc: Shuah Khan Cc: Prarit Bhargava Cc: Thomas Gleixner Cc: Richard Cochran Signed-off-by: John Stultz Signed-off-by: Shuah Khan --- tools/testing/selftests/timers/set-timer-lat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 2ed3267..4fc98c5 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -139,6 +139,13 @@ int do_timer(int clock_id, int flags) err = timer_create(clock_id, &se, &tm1); if (err) { + if ((clock_id == CLOCK_REALTIME_ALARM) || + (clock_id == CLOCK_BOOTTIME_ALARM)) { + printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", + clockstring(clock_id), + flags ? "ABSTIME":"RELTIME"); + return 0; + } printf("%s - timer_create() failed\n", clockstring(clock_id)); return -1; } -- cgit v1.1 From 52dd5576cd0d9d23b0b83b133d853a8ef074ee77 Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Wed, 1 Apr 2015 16:20:15 -0700 Subject: selftest/memfd: enable cross compilation Use the CC variable instead of hard coding gcc. Also clean up the compiler options by creating a CFLAGS variable. Signed-off-by: Tyler Baker Signed-off-by: Shuah Khan --- tools/testing/selftests/memfd/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 191dee9..69f08ab 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -1,17 +1,18 @@ +CC = $(CROSS_COMPILE)gcc CFLAGS += -D_FILE_OFFSET_BITS=64 CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ all: - gcc $(CFLAGS) memfd_test.c -o memfd_test + $(CC) $(CFLAGS) memfd_test.c -o memfd_test TEST_PROGS := memfd_test include ../lib.mk build_fuse: - gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt - gcc $(CFLAGS) fuse_test.c -o fuse_test + $(CC) $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt + $(CC) $(CFLAGS) fuse_test.c -o fuse_test run_fuse: build_fuse @./run_fuse_test.sh || echo "fuse_test: [FAIL]" -- cgit v1.1 From 365ce9997b40c763413e965bd6a3a87dfce01f74 Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Wed, 1 Apr 2015 16:20:17 -0700 Subject: selftest/mount: enable cross compilation Use the CC variable instead of hard coding gcc. Also clean up the compiler options by creating a CFLAGS variable. Signed-off-by: Tyler Baker Signed-off-by: Shuah Khan --- tools/testing/selftests/mount/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile index a5b367f..95580a9 100644 --- a/tools/testing/selftests/mount/Makefile +++ b/tools/testing/selftests/mount/Makefile @@ -1,9 +1,10 @@ # Makefile for mount selftests. - +CFLAGS = -Wall \ + -O2 all: unprivileged-remount-test unprivileged-remount-test: unprivileged-remount-test.c - gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test + $(CC) $(CFLAGS) unprivileged-remount-test.c -o unprivileged-remount-test include ../lib.mk -- cgit v1.1 From ab923bb9e2aedc9333aa0153a610a9de8993345e Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Wed, 1 Apr 2015 16:20:18 -0700 Subject: selftest/memfd: include default header install path Include the default path for INSTALL_HDR_PATH to make it less intrusive when cross building. Signed-off-by: Tyler Baker Signed-off-by: Shuah Khan --- tools/testing/selftests/memfd/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 69f08ab..3e7eb79 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -2,6 +2,7 @@ CC = $(CROSS_COMPILE)gcc CFLAGS += -D_FILE_OFFSET_BITS=64 CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ +CFLAGS += -I../../../../usr/include/ all: $(CC) $(CFLAGS) memfd_test.c -o memfd_test -- cgit v1.1 From 5de830490454315fa64fd42a6efa6ad83bf123da Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Wed, 1 Apr 2015 16:20:19 -0700 Subject: selftest/ipc: enable cross compilation Use the CC variable instead of hard coding gcc. Signed-off-by: Tyler Baker Signed-off-by: Shuah Khan --- tools/testing/selftests/ipc/Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile index 3b6013d..25d2e70 100644 --- a/tools/testing/selftests/ipc/Makefile +++ b/tools/testing/selftests/ipc/Makefile @@ -12,11 +12,7 @@ endif CFLAGS += -I../../../../usr/include/ all: -ifeq ($(ARCH),x86) - gcc $(CFLAGS) msgque.c -o msgque_test -else - echo "Not an x86 target, can't build msgque selftest" -endif + $(CC) $(CFLAGS) msgque.c -o msgque_test TEST_PROGS := msgque_test -- cgit v1.1 From 6886f41d885e1a0c0e95069e3c73d27eed89d8ed Mon Sep 17 00:00:00 2001 From: Tyler Baker Date: Wed, 1 Apr 2015 16:20:20 -0700 Subject: selftest/mqueue: enable cross compilation Use the CC variable instead of hard coding gcc. Also clean up the compiler options by creating a CFLAGS variable. Signed-off-by: Tyler Baker Signed-off-by: Shuah Khan --- tools/testing/selftests/mqueue/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile index 6ca7261..0e3b41e 100644 --- a/tools/testing/selftests/mqueue/Makefile +++ b/tools/testing/selftests/mqueue/Makefile @@ -1,6 +1,8 @@ +CFLAGS = -O2 + all: - gcc -O2 mq_open_tests.c -o mq_open_tests -lrt - gcc -O2 -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt + $(CC) $(CFLAGS) mq_open_tests.c -o mq_open_tests -lrt + $(CC) $(CFLAGS) -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt include ../lib.mk -- cgit v1.1 From 2bfd4d1f8c2bee8b0b8832be0c38d3916713625f Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 3 Apr 2015 09:27:58 +0900 Subject: ftracetest: Do not use usleep directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usleep is only provided on distros from Redhat so running ftracetest on other distro resulted in failures due to the missing usleep. The reason of using [u]sleep in the test was to generate (scheduler) events. It can be done various ways like this: yield() { ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1; } For more information to the history of this patch, please refer to: Link: http://lkml.kernel.org/r/1427329943-16896-1-git-send-email-namhyung@kernel.org Reported-by: Michael Ellerman Reported-by: Dave Jones Reported-by: Luis Henriques Suggested-by: Pádraig Brady Acked-by: Steven Rostedt Acked-by: Masami Hiramatsu Signed-off-by: Namhyung Kim Signed-off-by: Shuah Khan --- tools/testing/selftests/ftrace/test.d/event/event-enable.tc | 13 ++++++++++--- .../selftests/ftrace/test.d/event/subsystem-enable.tc | 13 ++++++++++--- .../selftests/ftrace/test.d/event/toplevel-enable.tc | 13 +++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc index dbddb78..87eb9d6 100644 --- a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc @@ -12,6 +12,10 @@ fail() { #msg exit $FAIL } +yield() { + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 +} + if [ ! -f set_event -o ! -d events/sched ]; then echo "event tracing is not supported" exit_unsupported @@ -21,7 +25,8 @@ reset_tracer do_reset echo 'sched:sched_switch' > set_event -usleep 1 + +yield count=`cat trace | grep sched_switch | wc -l` if [ $count -eq 0 ]; then @@ -31,7 +36,8 @@ fi do_reset echo 1 > events/sched/sched_switch/enable -usleep 1 + +yield count=`cat trace | grep sched_switch | wc -l` if [ $count -eq 0 ]; then @@ -41,7 +47,8 @@ fi do_reset echo 0 > events/sched/sched_switch/enable -usleep 1 + +yield count=`cat trace | grep sched_switch | wc -l` if [ $count -ne 0 ]; then diff --git a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc index ef9b95d..ced27ef 100644 --- a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc @@ -12,6 +12,10 @@ fail() { #msg exit $FAIL } +yield() { + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 +} + if [ ! -f set_event -o ! -d events/sched ]; then echo "event tracing is not supported" exit_unsupported @@ -21,7 +25,8 @@ reset_tracer do_reset echo 'sched:*' > set_event -usleep 1 + +yield count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` if [ $count -lt 3 ]; then @@ -31,7 +36,8 @@ fi do_reset echo 1 > events/sched/enable -usleep 1 + +yield count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` if [ $count -lt 3 ]; then @@ -41,7 +47,8 @@ fi do_reset echo 0 > events/sched/enable -usleep 1 + +yield count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` if [ $count -ne 0 ]; then diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc index af8cf01..0bb5df3 100644 --- a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc +++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc @@ -12,6 +12,10 @@ fail() { #msg exit $FAIL } +yield() { + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 +} + if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then echo "event tracing is not supported" exit_unsupported @@ -21,6 +25,9 @@ reset_tracer do_reset echo '*:*' > set_event + +yield + count=`cat trace | grep -v ^# | wc -l` if [ $count -eq 0 ]; then fail "none of events are recorded" @@ -29,6 +36,9 @@ fi do_reset echo 1 > events/enable + +yield + count=`cat trace | grep -v ^# | wc -l` if [ $count -eq 0 ]; then fail "none of events are recorded" @@ -37,6 +47,9 @@ fi do_reset echo 0 > events/enable + +yield + count=`cat trace | grep -v ^# | wc -l` if [ $count -ne 0 ]; then fail "any of events should not be recorded" -- cgit v1.1