Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'linux-kselftest-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kselftest updates from Shuah Khan:
"This is a milestone update in a sense. Several new tests and install
and packaging support is added in this update.

This update adds install and packaging tools developed on top of
back-end shared logic enhancemnets to run and install tests. In
addition several timer tests are added.

- New timer tests from John Stultz

- rtc test from Prarit Bhargava

- Enhancements to un and install tests from Michael Ellerman

- Install and packaging tools from Shuah Khan

- Cross-compilation enablement from Tyler Baker

- A couple of bug fixes"

* tag 'linux-kselftest-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (42 commits)
ftracetest: Do not use usleep directly
selftest/mqueue: enable cross compilation
selftest/ipc: enable cross compilation
selftest/memfd: include default header install path
selftest/mount: enable cross compilation
selftest/memfd: enable cross compilation
kselftests: timers: Make set-timer-lat fail more gracefully for !CAP_WAKE_ALARM
selftests: Change memory on-off-test.sh name to be unique
selftests: change cpu on-off-test.sh name to be unique
selftests/mount: Make git ignore all binaries in mount test suite
kselftests: timers: Reduce default runtime on inconsistency-check and set-timer-lat
ftracetest: Convert exit -1 to exit $FAIL
ftracetest: Cope properly with stack tracer not being enabled
tools, update rtctest.c to verify passage of time
Documentation, split up rtc.txt into documentation and test file
selftests: Add tool to generate kselftest tar archive
selftests: Add kselftest install tool
selftests: Set CC using CROSS_COMPILE once in lib.mk
selftests: Add install support for the powerpc tests
selftests/timers: Use shared logic to run and install tests
...

+3368 -461
+1 -263
Documentation/rtc.txt
··· 204 204 205 205 * RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code. 206 206 207 - If all else fails, check out the rtc-test.c driver! 208 - 209 - 210 - -------------------- 8< ---------------- 8< ----------------------------- 211 - 212 - /* 213 - * Real Time Clock Driver Test/Example Program 214 - * 215 - * Compile with: 216 - * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest 217 - * 218 - * Copyright (C) 1996, Paul Gortmaker. 219 - * 220 - * Released under the GNU General Public License, version 2, 221 - * included herein by reference. 222 - * 223 - */ 224 - 225 - #include <stdio.h> 226 - #include <linux/rtc.h> 227 - #include <sys/ioctl.h> 228 - #include <sys/time.h> 229 - #include <sys/types.h> 230 - #include <fcntl.h> 231 - #include <unistd.h> 232 - #include <stdlib.h> 233 - #include <errno.h> 234 - 235 - 236 - /* 237 - * This expects the new RTC class driver framework, working with 238 - * clocks that will often not be clones of what the PC-AT had. 239 - * Use the command line to specify another RTC if you need one. 240 - */ 241 - static const char default_rtc[] = "/dev/rtc0"; 242 - 243 - 244 - int main(int argc, char **argv) 245 - { 246 - int i, fd, retval, irqcount = 0; 247 - unsigned long tmp, data; 248 - struct rtc_time rtc_tm; 249 - const char *rtc = default_rtc; 250 - 251 - switch (argc) { 252 - case 2: 253 - rtc = argv[1]; 254 - /* FALLTHROUGH */ 255 - case 1: 256 - break; 257 - default: 258 - fprintf(stderr, "usage: rtctest [rtcdev]\n"); 259 - return 1; 260 - } 261 - 262 - fd = open(rtc, O_RDONLY); 263 - 264 - if (fd == -1) { 265 - perror(rtc); 266 - exit(errno); 267 - } 268 - 269 - fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); 270 - 271 - /* Turn on update interrupts (one per second) */ 272 - retval = ioctl(fd, RTC_UIE_ON, 0); 273 - if (retval == -1) { 274 - if (errno == ENOTTY) { 275 - fprintf(stderr, 276 - "\n...Update IRQs not supported.\n"); 277 - goto test_READ; 278 - } 279 - perror("RTC_UIE_ON ioctl"); 280 - exit(errno); 281 - } 282 - 283 - fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", 284 - rtc); 285 - fflush(stderr); 286 - for (i=1; i<6; i++) { 287 - /* This read will block */ 288 - retval = read(fd, &data, sizeof(unsigned long)); 289 - if (retval == -1) { 290 - perror("read"); 291 - exit(errno); 292 - } 293 - fprintf(stderr, " %d",i); 294 - fflush(stderr); 295 - irqcount++; 296 - } 297 - 298 - fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); 299 - fflush(stderr); 300 - for (i=1; i<6; i++) { 301 - struct timeval tv = {5, 0}; /* 5 second timeout on select */ 302 - fd_set readfds; 303 - 304 - FD_ZERO(&readfds); 305 - FD_SET(fd, &readfds); 306 - /* The select will wait until an RTC interrupt happens. */ 307 - retval = select(fd+1, &readfds, NULL, NULL, &tv); 308 - if (retval == -1) { 309 - perror("select"); 310 - exit(errno); 311 - } 312 - /* This read won't block unlike the select-less case above. */ 313 - retval = read(fd, &data, sizeof(unsigned long)); 314 - if (retval == -1) { 315 - perror("read"); 316 - exit(errno); 317 - } 318 - fprintf(stderr, " %d",i); 319 - fflush(stderr); 320 - irqcount++; 321 - } 322 - 323 - /* Turn off update interrupts */ 324 - retval = ioctl(fd, RTC_UIE_OFF, 0); 325 - if (retval == -1) { 326 - perror("RTC_UIE_OFF ioctl"); 327 - exit(errno); 328 - } 329 - 330 - test_READ: 331 - /* Read the RTC time/date */ 332 - retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); 333 - if (retval == -1) { 334 - perror("RTC_RD_TIME ioctl"); 335 - exit(errno); 336 - } 337 - 338 - fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", 339 - rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, 340 - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); 341 - 342 - /* Set the alarm to 5 sec in the future, and check for rollover */ 343 - rtc_tm.tm_sec += 5; 344 - if (rtc_tm.tm_sec >= 60) { 345 - rtc_tm.tm_sec %= 60; 346 - rtc_tm.tm_min++; 347 - } 348 - if (rtc_tm.tm_min == 60) { 349 - rtc_tm.tm_min = 0; 350 - rtc_tm.tm_hour++; 351 - } 352 - if (rtc_tm.tm_hour == 24) 353 - rtc_tm.tm_hour = 0; 354 - 355 - retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); 356 - if (retval == -1) { 357 - if (errno == ENOTTY) { 358 - fprintf(stderr, 359 - "\n...Alarm IRQs not supported.\n"); 360 - goto test_PIE; 361 - } 362 - perror("RTC_ALM_SET ioctl"); 363 - exit(errno); 364 - } 365 - 366 - /* Read the current alarm settings */ 367 - retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); 368 - if (retval == -1) { 369 - perror("RTC_ALM_READ ioctl"); 370 - exit(errno); 371 - } 372 - 373 - fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", 374 - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); 375 - 376 - /* Enable alarm interrupts */ 377 - retval = ioctl(fd, RTC_AIE_ON, 0); 378 - if (retval == -1) { 379 - perror("RTC_AIE_ON ioctl"); 380 - exit(errno); 381 - } 382 - 383 - fprintf(stderr, "Waiting 5 seconds for alarm..."); 384 - fflush(stderr); 385 - /* This blocks until the alarm ring causes an interrupt */ 386 - retval = read(fd, &data, sizeof(unsigned long)); 387 - if (retval == -1) { 388 - perror("read"); 389 - exit(errno); 390 - } 391 - irqcount++; 392 - fprintf(stderr, " okay. Alarm rang.\n"); 393 - 394 - /* Disable alarm interrupts */ 395 - retval = ioctl(fd, RTC_AIE_OFF, 0); 396 - if (retval == -1) { 397 - perror("RTC_AIE_OFF ioctl"); 398 - exit(errno); 399 - } 400 - 401 - test_PIE: 402 - /* Read periodic IRQ rate */ 403 - retval = ioctl(fd, RTC_IRQP_READ, &tmp); 404 - if (retval == -1) { 405 - /* not all RTCs support periodic IRQs */ 406 - if (errno == ENOTTY) { 407 - fprintf(stderr, "\nNo periodic IRQ support\n"); 408 - goto done; 409 - } 410 - perror("RTC_IRQP_READ ioctl"); 411 - exit(errno); 412 - } 413 - fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); 414 - 415 - fprintf(stderr, "Counting 20 interrupts at:"); 416 - fflush(stderr); 417 - 418 - /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ 419 - for (tmp=2; tmp<=64; tmp*=2) { 420 - 421 - retval = ioctl(fd, RTC_IRQP_SET, tmp); 422 - if (retval == -1) { 423 - /* not all RTCs can change their periodic IRQ rate */ 424 - if (errno == ENOTTY) { 425 - fprintf(stderr, 426 - "\n...Periodic IRQ rate is fixed\n"); 427 - goto done; 428 - } 429 - perror("RTC_IRQP_SET ioctl"); 430 - exit(errno); 431 - } 432 - 433 - fprintf(stderr, "\n%ldHz:\t", tmp); 434 - fflush(stderr); 435 - 436 - /* Enable periodic interrupts */ 437 - retval = ioctl(fd, RTC_PIE_ON, 0); 438 - if (retval == -1) { 439 - perror("RTC_PIE_ON ioctl"); 440 - exit(errno); 441 - } 442 - 443 - for (i=1; i<21; i++) { 444 - /* This blocks */ 445 - retval = read(fd, &data, sizeof(unsigned long)); 446 - if (retval == -1) { 447 - perror("read"); 448 - exit(errno); 449 - } 450 - fprintf(stderr, " %d",i); 451 - fflush(stderr); 452 - irqcount++; 453 - } 454 - 455 - /* Disable periodic interrupts */ 456 - retval = ioctl(fd, RTC_PIE_OFF, 0); 457 - if (retval == -1) { 458 - perror("RTC_PIE_OFF ioctl"); 459 - exit(errno); 460 - } 461 - } 462 - 463 - done: 464 - fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); 465 - 466 - close(fd); 467 - 468 - return 0; 469 - } 207 + If all else fails, check out the tools/testing/selftests/timers/rtctest.c test!
+1
MAINTAINERS
··· 8559 8559 F: kernel/time/clocksource.c 8560 8560 F: kernel/time/time*.c 8561 8561 F: kernel/time/ntp.c 8562 + F: tools/testing/selftests/timers/ 8562 8563 8563 8564 SC1200 WDT DRIVER 8564 8565 M: Zwane Mwaikambo <zwanem@gmail.com>
+33
tools/testing/selftests/Makefile
··· 55 55 make -C $$TARGET clean; \ 56 56 done; 57 57 58 + INSTALL_PATH ?= install 59 + INSTALL_PATH := $(abspath $(INSTALL_PATH)) 60 + ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh 61 + 62 + install: 63 + ifdef INSTALL_PATH 64 + @# Ask all targets to install their files 65 + mkdir -p $(INSTALL_PATH) 66 + for TARGET in $(TARGETS); do \ 67 + mkdir -p $(INSTALL_PATH)/$$TARGET ; \ 68 + make -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ 69 + done; 70 + 71 + @# Ask all targets to emit their test scripts 72 + echo "#!/bin/bash" > $(ALL_SCRIPT) 73 + echo "cd \$$(dirname \$$0)" >> $(ALL_SCRIPT) 74 + echo "ROOT=\$$PWD" >> $(ALL_SCRIPT) 75 + 76 + for TARGET in $(TARGETS); do \ 77 + echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ 78 + echo "echo ========================================" >> $(ALL_SCRIPT); \ 79 + echo "cd $$TARGET" >> $(ALL_SCRIPT); \ 80 + make -s --no-print-directory -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ 81 + echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ 82 + done; 83 + 84 + chmod u+x $(ALL_SCRIPT) 85 + else 86 + $(error Error: set INSTALL_PATH to use install) 87 + endif 88 + 58 89 clean: 59 90 for TARGET in $(TARGETS); do \ 60 91 make -C $$TARGET clean; \ 61 92 done; 93 + 94 + .PHONY: install
+3 -2
tools/testing/selftests/breakpoints/Makefile
··· 16 16 echo "Not an x86 target, can't build breakpoints selftests" 17 17 endif 18 18 19 - run_tests: 20 - @./breakpoint_test || echo "breakpoints selftests: [FAIL]" 19 + TEST_PROGS := breakpoint_test 20 + 21 + include ../lib.mk 21 22 22 23 clean: 23 24 rm -fr breakpoint_test
+4 -3
tools/testing/selftests/cpu-hotplug/Makefile
··· 1 1 all: 2 2 3 - run_tests: 4 - @/bin/bash ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]" 3 + TEST_PROGS := cpu-on-off-test.sh 4 + 5 + include ../lib.mk 5 6 6 7 run_full_test: 7 - @/bin/bash ./on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" 8 + @/bin/bash ./cpu-on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" 8 9 9 10 clean:
tools/testing/selftests/cpu-hotplug/on-off-test.sh tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+4 -3
tools/testing/selftests/efivarfs/Makefile
··· 1 - CC = $(CROSS_COMPILE)gcc 2 1 CFLAGS = -Wall 3 2 4 3 test_objs = open-unlink create-read 5 4 6 5 all: $(test_objs) 7 6 8 - run_tests: all 9 - @/bin/bash ./efivarfs.sh || echo "efivarfs selftests: [FAIL]" 7 + TEST_PROGS := efivarfs.sh 8 + TEST_FILES := $(test_objs) 9 + 10 + include ../lib.mk 10 11 11 12 clean: 12 13 rm -f $(test_objs)
tools/testing/selftests/efivarfs/efivarfs.sh
+6 -3
tools/testing/selftests/exec/Makefile
··· 1 - CC = $(CROSS_COMPILE)gcc 2 1 CFLAGS = -Wall 3 2 BINARIES = execveat 4 3 DEPS = execveat.symlink execveat.denatured script subdir ··· 17 18 %: %.c 18 19 $(CC) $(CFLAGS) -o $@ $^ 19 20 20 - run_tests: all 21 - ./execveat 21 + TEST_PROGS := execveat 22 + TEST_FILES := $(DEPS) 23 + 24 + include ../lib.mk 25 + 26 + override EMIT_TESTS := echo "mkdir -p subdir; (./execveat && echo \"selftests: execveat [PASS]\") || echo \"selftests: execveat [FAIL]\"" 22 27 23 28 clean: 24 29 rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx*
+2 -18
tools/testing/selftests/firmware/Makefile
··· 3 3 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 4 4 all: 5 5 6 - fw_filesystem: 7 - @if /bin/sh ./fw_filesystem.sh ; then \ 8 - echo "fw_filesystem: ok"; \ 9 - else \ 10 - echo "fw_filesystem: [FAIL]"; \ 11 - exit 1; \ 12 - fi 6 + TEST_PROGS := fw_filesystem.sh fw_userhelper.sh 13 7 14 - fw_userhelper: 15 - @if /bin/sh ./fw_userhelper.sh ; then \ 16 - echo "fw_userhelper: ok"; \ 17 - else \ 18 - echo "fw_userhelper: [FAIL]"; \ 19 - exit 1; \ 20 - fi 21 - 22 - run_tests: all fw_filesystem fw_userhelper 8 + include ../lib.mk 23 9 24 10 # Nothing to clean up. 25 11 clean: 26 - 27 - .PHONY: all clean run_tests fw_filesystem fw_userhelper
tools/testing/selftests/firmware/fw_filesystem.sh
tools/testing/selftests/firmware/fw_userhelper.sh
+3 -2
tools/testing/selftests/ftrace/Makefile
··· 1 1 all: 2 2 3 - run_tests: 4 - @/bin/sh ./ftracetest || echo "ftrace selftests: [FAIL]" 3 + TEST_PROGS := ftracetest 4 + 5 + include ../lib.mk 5 6 6 7 clean: 7 8 rm -rf logs/*
+1 -1
tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
··· 2 2 # description: Basic event tracing check 3 3 test -f available_events -a -f set_event -a -d events 4 4 # check scheduler events are available 5 - grep -q sched available_events && exit 0 || exit -1 5 + grep -q sched available_events && exit 0 || exit $FAIL
+11 -4
tools/testing/selftests/ftrace/test.d/event/event-enable.tc
··· 9 9 fail() { #msg 10 10 do_reset 11 11 echo $1 12 - exit -1 12 + exit $FAIL 13 + } 14 + 15 + yield() { 16 + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 13 17 } 14 18 15 19 if [ ! -f set_event -o ! -d events/sched ]; then ··· 25 21 do_reset 26 22 27 23 echo 'sched:sched_switch' > set_event 28 - usleep 1 24 + 25 + yield 29 26 30 27 count=`cat trace | grep sched_switch | wc -l` 31 28 if [ $count -eq 0 ]; then ··· 36 31 do_reset 37 32 38 33 echo 1 > events/sched/sched_switch/enable 39 - usleep 1 34 + 35 + yield 40 36 41 37 count=`cat trace | grep sched_switch | wc -l` 42 38 if [ $count -eq 0 ]; then ··· 47 41 do_reset 48 42 49 43 echo 0 > events/sched/sched_switch/enable 50 - usleep 1 44 + 45 + yield 51 46 52 47 count=`cat trace | grep sched_switch | wc -l` 53 48 if [ $count -ne 0 ]; then
+11 -4
tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
··· 9 9 fail() { #msg 10 10 do_reset 11 11 echo $1 12 - exit -1 12 + exit $FAIL 13 + } 14 + 15 + yield() { 16 + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 13 17 } 14 18 15 19 if [ ! -f set_event -o ! -d events/sched ]; then ··· 25 21 do_reset 26 22 27 23 echo 'sched:*' > set_event 28 - usleep 1 24 + 25 + yield 29 26 30 27 count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` 31 28 if [ $count -lt 3 ]; then ··· 36 31 do_reset 37 32 38 33 echo 1 > events/sched/enable 39 - usleep 1 34 + 35 + yield 40 36 41 37 count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` 42 38 if [ $count -lt 3 ]; then ··· 47 41 do_reset 48 42 49 43 echo 0 > events/sched/enable 50 - usleep 1 44 + 45 + yield 51 46 52 47 count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l` 53 48 if [ $count -ne 0 ]; then
+14 -1
tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
··· 9 9 fail() { #msg 10 10 do_reset 11 11 echo $1 12 - exit -1 12 + exit $FAIL 13 + } 14 + 15 + yield() { 16 + ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1 13 17 } 14 18 15 19 if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then ··· 25 21 do_reset 26 22 27 23 echo '*:*' > set_event 24 + 25 + yield 26 + 28 27 count=`cat trace | grep -v ^# | wc -l` 29 28 if [ $count -eq 0 ]; then 30 29 fail "none of events are recorded" ··· 36 29 do_reset 37 30 38 31 echo 1 > events/enable 32 + 33 + yield 34 + 39 35 count=`cat trace | grep -v ^# | wc -l` 40 36 if [ $count -eq 0 ]; then 41 37 fail "none of events are recorded" ··· 47 37 do_reset 48 38 49 39 echo 0 > events/enable 40 + 41 + yield 42 + 50 43 count=`cat trace | grep -v ^# | wc -l` 51 44 if [ $count -ne 0 ]; then 52 45 fail "any of events should not be recorded"
+4 -2
tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
··· 16 16 17 17 do_reset() { 18 18 reset_tracer 19 - echo 0 > /proc/sys/kernel/stack_tracer_enabled 19 + if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then 20 + echo 0 > /proc/sys/kernel/stack_tracer_enabled 21 + fi 20 22 enable_tracing 21 23 clear_trace 22 24 echo > set_ftrace_filter ··· 27 25 fail() { # msg 28 26 do_reset 29 27 echo $1 30 - exit -1 28 + exit $FAIL 31 29 } 32 30 33 31 disable_tracing
+1 -1
tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
··· 17 17 fail() { # msg 18 18 do_reset 19 19 echo $1 20 - exit -1 20 + exit $FAIL 21 21 } 22 22 23 23 disable_tracing
+1 -1
tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
··· 31 31 reset_tracer 32 32 echo > set_ftrace_filter 33 33 echo $1 34 - exit -1 34 + exit $FAIL 35 35 } 36 36 37 37 echo "Testing function tracer with profiler:"
+55
tools/testing/selftests/gen_kselftest_tar.sh
··· 1 + #!/bin/bash 2 + # 3 + # gen_kselftest_tar 4 + # Generate kselftest tarball 5 + # Author: Shuah Khan <shuahkh@osg.samsung.com> 6 + # Copyright (C) 2015 Samsung Electronics Co., Ltd. 7 + 8 + # This software may be freely redistributed under the terms of the GNU 9 + # General Public License (GPLv2). 10 + 11 + # main 12 + main() 13 + { 14 + if [ "$#" -eq 0 ]; then 15 + echo "$0: Generating default compression gzip" 16 + copts="cvzf" 17 + ext=".tar.gz" 18 + else 19 + case "$1" in 20 + tar) 21 + copts="cvf" 22 + ext=".tar" 23 + ;; 24 + targz) 25 + copts="cvzf" 26 + ext=".tar.gz" 27 + ;; 28 + tarbz2) 29 + copts="cvjf" 30 + ext=".tar.bz2" 31 + ;; 32 + tarxz) 33 + copts="cvJf" 34 + ext=".tar.xz" 35 + ;; 36 + *) 37 + echo "Unknown tarball format $1" 38 + exit 1 39 + ;; 40 + esac 41 + fi 42 + 43 + install_dir=./kselftest 44 + 45 + # Run install using INSTALL_KSFT_PATH override to generate install 46 + # directory 47 + ./kselftest_install.sh 48 + tar $copts kselftest${ext} $install_dir 49 + echo "Kselftest archive kselftest${ext} created!" 50 + 51 + # clean up install directory 52 + rm -rf kselftest 53 + } 54 + 55 + main "$@"
+4 -7
tools/testing/selftests/ipc/Makefile
··· 12 12 CFLAGS += -I../../../../usr/include/ 13 13 14 14 all: 15 - ifeq ($(ARCH),x86) 16 - gcc $(CFLAGS) msgque.c -o msgque_test 17 - else 18 - echo "Not an x86 target, can't build msgque selftest" 19 - endif 15 + $(CC) $(CFLAGS) msgque.c -o msgque_test 20 16 21 - run_tests: all 22 - ./msgque_test 17 + TEST_PROGS := msgque_test 18 + 19 + include ../lib.mk 23 20 24 21 clean: 25 22 rm -fr ./msgque_test
+3 -3
tools/testing/selftests/kcmp/Makefile
··· 1 - CC := $(CROSS_COMPILE)$(CC) 2 1 CFLAGS += -I../../../../usr/include/ 3 2 4 3 all: kcmp_test 5 4 6 - run_tests: all 7 - @./kcmp_test || echo "kcmp_test: [FAIL]" 5 + TEST_PROGS := kcmp_test 6 + 7 + include ../lib.mk 8 8 9 9 clean: 10 10 $(RM) kcmp_test kcmp-test-file
+37
tools/testing/selftests/kselftest_install.sh
··· 1 + #!/bin/bash 2 + # 3 + # Kselftest Install 4 + # Install kselftest tests 5 + # Author: Shuah Khan <shuahkh@osg.samsung.com> 6 + # Copyright (C) 2015 Samsung Electronics Co., Ltd. 7 + 8 + # This software may be freely redistributed under the terms of the GNU 9 + # General Public License (GPLv2). 10 + 11 + install_loc=`pwd` 12 + 13 + main() 14 + { 15 + if [ $(basename $install_loc) != "selftests" ]; then 16 + echo "$0: Please run it in selftests directory ..." 17 + exit 1; 18 + fi 19 + if [ "$#" -eq 0 ]; then 20 + echo "$0: Installing in default location - $install_loc ..." 21 + elif [ ! -d "$1" ]; then 22 + echo "$0: $1 doesn't exist!!" 23 + exit 1; 24 + else 25 + install_loc=$1 26 + echo "$0: Installing in specified location - $install_loc ..." 27 + fi 28 + 29 + install_dir=$install_loc/kselftest 30 + 31 + # Create install directory 32 + mkdir -p $install_dir 33 + # Build tests 34 + INSTALL_PATH=$install_dir make install 35 + } 36 + 37 + main "$@"
+35
tools/testing/selftests/lib.mk
··· 1 + # This mimics the top-level Makefile. We do it explicitly here so that this 2 + # Makefile can operate with or without the kbuild infrastructure. 3 + CC := $(CROSS_COMPILE)gcc 4 + 5 + define RUN_TESTS 6 + @for TEST in $(TEST_PROGS); do \ 7 + (./$$TEST && echo "selftests: $$TEST [PASS]") || echo "selftests: $$TEST [FAIL]"; \ 8 + done; 9 + endef 10 + 11 + run_tests: all 12 + $(RUN_TESTS) 13 + 14 + define INSTALL_RULE 15 + mkdir -p $(INSTALL_PATH) 16 + install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) 17 + endef 18 + 19 + install: all 20 + ifdef INSTALL_PATH 21 + $(INSTALL_RULE) 22 + else 23 + $(error Error: set INSTALL_PATH to use install) 24 + endif 25 + 26 + define EMIT_TESTS 27 + @for TEST in $(TEST_PROGS); do \ 28 + echo "(./$$TEST && echo \"selftests: $$TEST [PASS]\") || echo \"selftests: $$TEST [FAIL]\""; \ 29 + done; 30 + endef 31 + 32 + emit_tests: 33 + $(EMIT_TESTS) 34 + 35 + .PHONY: run_tests all clean install emit_tests
+8 -6
tools/testing/selftests/memfd/Makefile
··· 1 + CC = $(CROSS_COMPILE)gcc 1 2 CFLAGS += -D_FILE_OFFSET_BITS=64 2 3 CFLAGS += -I../../../../include/uapi/ 3 4 CFLAGS += -I../../../../include/ 5 + CFLAGS += -I../../../../usr/include/ 4 6 5 7 all: 6 - gcc $(CFLAGS) memfd_test.c -o memfd_test 8 + $(CC) $(CFLAGS) memfd_test.c -o memfd_test 7 9 8 - run_tests: all 9 - gcc $(CFLAGS) memfd_test.c -o memfd_test 10 - @./memfd_test || echo "memfd_test: [FAIL]" 10 + TEST_PROGS := memfd_test 11 + 12 + include ../lib.mk 11 13 12 14 build_fuse: 13 - gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt 14 - gcc $(CFLAGS) fuse_test.c -o fuse_test 15 + $(CC) $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt 16 + $(CC) $(CFLAGS) fuse_test.c -o fuse_test 15 17 16 18 run_fuse: build_fuse 17 19 @./run_fuse_test.sh || echo "fuse_test: [FAIL]"
+6 -3
tools/testing/selftests/memory-hotplug/Makefile
··· 1 1 all: 2 2 3 - run_tests: 4 - @/bin/bash ./on-off-test.sh -r 2 || echo "memory-hotplug selftests: [FAIL]" 3 + include ../lib.mk 4 + 5 + TEST_PROGS := mem-on-off-test.sh 6 + override RUN_TESTS := ./mem-on-off-test.sh -r 2 || echo "selftests: memory-hotplug [FAIL]" 7 + override EMIT_TESTS := echo "$(RUN_TESTS)" 5 8 6 9 run_full_test: 7 - @/bin/bash ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" 10 + @/bin/bash ./mem-on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" 8 11 9 12 clean:
tools/testing/selftests/memory-hotplug/on-off-test.sh tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
+1
tools/testing/selftests/mount/.gitignore
··· 1 + unprivileged-remount-test
+7 -8
tools/testing/selftests/mount/Makefile
··· 1 1 # Makefile for mount selftests. 2 - 2 + CFLAGS = -Wall \ 3 + -O2 3 4 all: unprivileged-remount-test 4 5 5 6 unprivileged-remount-test: unprivileged-remount-test.c 6 - gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test 7 + $(CC) $(CFLAGS) unprivileged-remount-test.c -o unprivileged-remount-test 7 8 8 - # Allow specific tests to be selected. 9 - test_unprivileged_remount: unprivileged-remount-test 10 - @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi 9 + include ../lib.mk 11 10 12 - run_tests: all test_unprivileged_remount 11 + TEST_PROGS := unprivileged-remount-test 12 + override RUN_TESTS := if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi 13 + override EMIT_TESTS := echo "$(RUN_TESTS)" 13 14 14 15 clean: 15 16 rm -f unprivileged-remount-test 16 - 17 - .PHONY: all test_unprivileged_remount
+18 -6
tools/testing/selftests/mqueue/Makefile
··· 1 - all: 2 - gcc -O2 mq_open_tests.c -o mq_open_tests -lrt 3 - gcc -O2 -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt 1 + CFLAGS = -O2 4 2 5 - run_tests: 6 - @./mq_open_tests /test1 || echo "mq_open_tests: [FAIL]" 7 - @./mq_perf_tests || echo "mq_perf_tests: [FAIL]" 3 + all: 4 + $(CC) $(CFLAGS) mq_open_tests.c -o mq_open_tests -lrt 5 + $(CC) $(CFLAGS) -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt 6 + 7 + include ../lib.mk 8 + 9 + override define RUN_TESTS 10 + @./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]" 11 + @./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]" 12 + endef 13 + 14 + TEST_PROGS := mq_open_tests mq_perf_tests 15 + 16 + override define EMIT_TESTS 17 + echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\"" 18 + echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\"" 19 + endef 8 20 9 21 clean: 10 22 rm -f mq_open_tests mq_perf_tests
+5 -5
tools/testing/selftests/net/Makefile
··· 1 1 # Makefile for net selftests 2 2 3 - CC = $(CROSS_COMPILE)gcc 4 3 CFLAGS = -Wall -O2 -g 5 4 6 5 CFLAGS += -I../../../../usr/include/ ··· 10 11 %: %.c 11 12 $(CC) $(CFLAGS) -o $@ $^ 12 13 13 - run_tests: all 14 - @/bin/sh ./run_netsocktests || echo "sockettests: [FAIL]" 15 - @/bin/sh ./run_afpackettests || echo "afpackettests: [FAIL]" 16 - ./test_bpf.sh 14 + TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh 15 + TEST_FILES := $(NET_PROGS) 16 + 17 + include ../lib.mk 18 + 17 19 clean: 18 20 $(RM) $(NET_PROGS)
tools/testing/selftests/net/run_afpackettests
tools/testing/selftests/net/run_netsocktests
+18 -4
tools/testing/selftests/powerpc/Makefile
··· 8 8 9 9 GIT_VERSION = $(shell git describe --always --long --dirty || echo "unknown") 10 10 11 - CC := $(CROSS_COMPILE)$(CC) 12 11 CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $(CFLAGS) 13 12 14 - export CC CFLAGS 13 + export CFLAGS 15 14 16 15 TARGETS = pmu copyloops mm tm primitives stringloops 17 16 ··· 21 22 $(TARGETS): 22 23 $(MAKE) -k -C $@ all 23 24 24 - run_tests: all 25 + include ../lib.mk 26 + 27 + override define RUN_TESTS 25 28 @for TARGET in $(TARGETS); do \ 26 29 $(MAKE) -C $$TARGET run_tests; \ 27 30 done; 31 + endef 32 + 33 + override define INSTALL_RULE 34 + @for TARGET in $(TARGETS); do \ 35 + $(MAKE) -C $$TARGET install; \ 36 + done; 37 + endef 38 + 39 + override define EMIT_TESTS 40 + @for TARGET in $(TARGETS); do \ 41 + $(MAKE) -s -C $$TARGET emit_tests; \ 42 + done; 43 + endef 28 44 29 45 clean: 30 46 @for TARGET in $(TARGETS); do \ ··· 50 36 tags: 51 37 find . -name '*.c' -o -name '*.h' | xargs ctags 52 38 53 - .PHONY: all run_tests clean tags $(TARGETS) 39 + .PHONY: tags $(TARGETS)
+5 -10
tools/testing/selftests/powerpc/copyloops/Makefile
··· 6 6 # Use our CFLAGS for the implicit .S rule 7 7 ASFLAGS = $(CFLAGS) 8 8 9 - PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 9 + TEST_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 10 10 EXTRA_SOURCES := validate.c ../harness.c 11 11 12 - all: $(PROGS) 12 + all: $(TEST_PROGS) 13 13 14 14 copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base 15 15 copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 16 16 memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy 17 17 memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 18 18 19 - $(PROGS): $(EXTRA_SOURCES) 19 + $(TEST_PROGS): $(EXTRA_SOURCES) 20 20 21 - run_tests: all 22 - @-for PROG in $(PROGS); do \ 23 - ./$$PROG; \ 24 - done; 21 + include ../../lib.mk 25 22 26 23 clean: 27 - rm -f $(PROGS) *.o 28 - 29 - .PHONY: all run_tests clean 24 + rm -f $(TEST_PROGS) *.o
+5 -10
tools/testing/selftests/powerpc/mm/Makefile
··· 1 1 noarg: 2 2 $(MAKE) -C ../ 3 3 4 - PROGS := hugetlb_vs_thp_test subpage_prot 4 + TEST_PROGS := hugetlb_vs_thp_test subpage_prot 5 5 6 - all: $(PROGS) tempfile 6 + all: $(TEST_PROGS) tempfile 7 7 8 - $(PROGS): ../harness.c 8 + $(TEST_PROGS): ../harness.c 9 9 10 - run_tests: all 11 - @-for PROG in $(PROGS); do \ 12 - ./$$PROG; \ 13 - done; 10 + include ../../lib.mk 14 11 15 12 tempfile: 16 13 dd if=/dev/zero of=tempfile bs=64k count=1 17 14 18 15 clean: 19 - rm -f $(PROGS) tempfile 20 - 21 - .PHONY: all run_tests clean 16 + rm -f $(TEST_PROGS) tempfile
+27 -23
tools/testing/selftests/powerpc/pmu/Makefile
··· 1 1 noarg: 2 2 $(MAKE) -C ../ 3 3 4 - PROGS := count_instructions l3_bank_test per_event_excludes 4 + TEST_PROGS := count_instructions l3_bank_test per_event_excludes 5 5 EXTRA_SOURCES := ../harness.c event.c lib.c 6 6 7 - SUB_TARGETS = ebb 7 + all: $(TEST_PROGS) ebb 8 8 9 - all: $(PROGS) $(SUB_TARGETS) 10 - 11 - $(PROGS): $(EXTRA_SOURCES) 9 + $(TEST_PROGS): $(EXTRA_SOURCES) 12 10 13 11 # loop.S can only be built 64-bit 14 12 count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) 15 13 $(CC) $(CFLAGS) -m64 -o $@ $^ 16 14 17 - run_tests: all sub_run_tests 18 - @-for PROG in $(PROGS); do \ 19 - ./$$PROG; \ 20 - done; 15 + include ../../lib.mk 21 16 22 - clean: sub_clean 23 - rm -f $(PROGS) loop.o 17 + DEFAULT_RUN_TESTS := $(RUN_TESTS) 18 + override define RUN_TESTS 19 + $(DEFAULT_RUN_TESTS) 20 + $(MAKE) -C ebb run_tests 21 + endef 24 22 25 - $(SUB_TARGETS): 23 + DEFAULT_EMIT_TESTS := $(EMIT_TESTS) 24 + override define EMIT_TESTS 25 + $(DEFAULT_EMIT_TESTS) 26 + $(MAKE) -s -C ebb emit_tests 27 + endef 28 + 29 + DEFAULT_INSTALL := $(INSTALL_RULE) 30 + override define INSTALL_RULE 31 + $(DEFAULT_INSTALL_RULE) 32 + $(MAKE) -C ebb install 33 + endef 34 + 35 + clean: 36 + rm -f $(TEST_PROGS) loop.o 37 + $(MAKE) -C ebb clean 38 + 39 + ebb: 26 40 $(MAKE) -k -C $@ all 27 41 28 - sub_run_tests: all 29 - @for TARGET in $(SUB_TARGETS); do \ 30 - $(MAKE) -C $$TARGET run_tests; \ 31 - done; 32 - 33 - sub_clean: 34 - @for TARGET in $(SUB_TARGETS); do \ 35 - $(MAKE) -C $$TARGET clean; \ 36 - done; 37 - 38 - .PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS) 42 + .PHONY: all run_tests clean ebb
+5 -8
tools/testing/selftests/powerpc/pmu/ebb/Makefile
··· 4 4 # The EBB handler is 64-bit code and everything links against it 5 5 CFLAGS += -m64 6 6 7 - PROGS := reg_access_test event_attributes_test cycles_test \ 7 + TEST_PROGS := reg_access_test event_attributes_test cycles_test \ 8 8 cycles_with_freeze_test pmc56_overflow_test \ 9 9 ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ 10 10 cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ ··· 16 16 lost_exception_test no_handler_test \ 17 17 cycles_with_mmcr2_test 18 18 19 - all: $(PROGS) 19 + all: $(TEST_PROGS) 20 20 21 - $(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S 21 + $(TEST_PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S 22 22 23 23 instruction_count_test: ../loop.S 24 24 25 25 lost_exception_test: ../lib.c 26 26 27 - run_tests: all 28 - @-for PROG in $(PROGS); do \ 29 - ./$$PROG; \ 30 - done; 27 + include ../../../lib.mk 31 28 32 29 clean: 33 - rm -f $(PROGS) 30 + rm -f $(TEST_PROGS)
+5 -10
tools/testing/selftests/powerpc/primitives/Makefile
··· 1 1 CFLAGS += -I$(CURDIR) 2 2 3 - PROGS := load_unaligned_zeropad 3 + TEST_PROGS := load_unaligned_zeropad 4 4 5 - all: $(PROGS) 5 + all: $(TEST_PROGS) 6 6 7 - $(PROGS): ../harness.c 7 + $(TEST_PROGS): ../harness.c 8 8 9 - run_tests: all 10 - @-for PROG in $(PROGS); do \ 11 - ./$$PROG; \ 12 - done; 9 + include ../../lib.mk 13 10 14 11 clean: 15 - rm -f $(PROGS) *.o 16 - 17 - .PHONY: all run_tests clean 12 + rm -f $(TEST_PROGS) *.o
+5 -10
tools/testing/selftests/powerpc/stringloops/Makefile
··· 2 2 CFLAGS += -m64 3 3 CFLAGS += -I$(CURDIR) 4 4 5 - PROGS := memcmp 5 + TEST_PROGS := memcmp 6 6 EXTRA_SOURCES := memcmp_64.S ../harness.c 7 7 8 - all: $(PROGS) 8 + all: $(TEST_PROGS) 9 9 10 - $(PROGS): $(EXTRA_SOURCES) 10 + $(TEST_PROGS): $(EXTRA_SOURCES) 11 11 12 - run_tests: all 13 - @-for PROG in $(PROGS); do \ 14 - ./$$PROG; \ 15 - done; 12 + include ../../lib.mk 16 13 17 14 clean: 18 - rm -f $(PROGS) *.o 19 - 20 - .PHONY: all run_tests clean 15 + rm -f $(TEST_PROGS) *.o
+5 -10
tools/testing/selftests/powerpc/tm/Makefile
··· 1 - PROGS := tm-resched-dscr 1 + TEST_PROGS := tm-resched-dscr 2 2 3 - all: $(PROGS) 3 + all: $(TEST_PROGS) 4 4 5 - $(PROGS): ../harness.c 5 + $(TEST_PROGS): ../harness.c 6 6 7 - run_tests: all 8 - @-for PROG in $(PROGS); do \ 9 - ./$$PROG; \ 10 - done; 7 + include ../../lib.mk 11 8 12 9 clean: 13 - rm -f $(PROGS) *.o 14 - 15 - .PHONY: all run_tests clean 10 + rm -f $(TEST_PROGS) *.o
+3 -2
tools/testing/selftests/ptrace/Makefile
··· 6 6 clean: 7 7 rm -f peeksiginfo 8 8 9 - run_tests: all 10 - @./peeksiginfo || echo "peeksiginfo selftests: [FAIL]" 9 + TEST_PROGS := peeksiginfo 10 + 11 + include ../lib.mk
+3 -4
tools/testing/selftests/size/Makefile
··· 1 - CC = $(CROSS_COMPILE)gcc 2 - 3 1 all: get_size 4 2 5 3 get_size: get_size.c 6 4 $(CC) -static -ffreestanding -nostartfiles -s $< -o $@ 7 5 8 - run_tests: all 9 - ./get_size 6 + TEST_PROGS := get_size 7 + 8 + include ../lib.mk 10 9 11 10 clean: 12 11 $(RM) get_size
+3 -9
tools/testing/selftests/sysctl/Makefile
··· 4 4 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests". 5 5 all: 6 6 7 - # Allow specific tests to be selected. 8 - test_num: 9 - @/bin/sh ./run_numerictests 7 + TEST_PROGS := run_numerictests run_stringtests 8 + TEST_FILES := common_tests 10 9 11 - test_string: 12 - @/bin/sh ./run_stringtests 13 - 14 - run_tests: all test_num test_string 10 + include ../lib.mk 15 11 16 12 # Nothing to clean up. 17 13 clean: 18 - 19 - .PHONY: all run_tests clean test_num test_string
tools/testing/selftests/sysctl/run_numerictests
tools/testing/selftests/sysctl/run_stringtests
+33 -5
tools/testing/selftests/timers/Makefile
··· 1 - all: 2 - gcc posix_timers.c -o posix_timers -lrt 1 + CC = $(CROSS_COMPILE)gcc 2 + BUILD_FLAGS = -DKTEST 3 + CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) 4 + LDFLAGS += -lrt -lpthread 3 5 4 - run_tests: all 5 - ./posix_timers 6 + # these are all "safe" tests that don't modify 7 + # system time or require escalated privledges 8 + TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ 9 + inconsistency-check raw_skew threadtest rtctest 10 + 11 + TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \ 12 + skew_consistency clocksource-switch leap-a-day \ 13 + leapcrash set-tai set-2038 14 + 15 + bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED) 16 + 17 + all: ${bins} 18 + 19 + include ../lib.mk 20 + 21 + # these tests require escalated privledges 22 + # and may modify the system time or trigger 23 + # other behavior like suspend 24 + run_destructive_tests: run_tests 25 + ./alarmtimer-suspend 26 + ./valid-adjtimex 27 + ./change_skew 28 + ./skew_consistency 29 + ./clocksource-switch 30 + ./leap-a-day -s -i 10 31 + ./leapcrash 32 + ./set-tai 33 + ./set-2038 6 34 7 35 clean: 8 - rm -f ./posix_timers 36 + rm -f ${bins}
+185
tools/testing/selftests/timers/alarmtimer-suspend.c
··· 1 + /* alarmtimer suspend test 2 + * John Stultz (john.stultz@linaro.org) 3 + * (C) Copyright Linaro 2013 4 + * Licensed under the GPLv2 5 + * 6 + * This test makes sure the alarmtimer & RTC wakeup code is 7 + * functioning. 8 + * 9 + * To build: 10 + * $ gcc alarmtimer-suspend.c -o alarmtimer-suspend -lrt 11 + * 12 + * This program is free software: you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation, either version 2 of the License, or 15 + * (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + */ 22 + 23 + 24 + #include <stdio.h> 25 + #include <unistd.h> 26 + #include <time.h> 27 + #include <string.h> 28 + #include <signal.h> 29 + #include <stdlib.h> 30 + #include <pthread.h> 31 + #ifdef KTEST 32 + #include "../kselftest.h" 33 + #else 34 + static inline int ksft_exit_pass(void) 35 + { 36 + exit(0); 37 + } 38 + static inline int ksft_exit_fail(void) 39 + { 40 + exit(1); 41 + } 42 + #endif 43 + 44 + #define CLOCK_REALTIME 0 45 + #define CLOCK_MONOTONIC 1 46 + #define CLOCK_PROCESS_CPUTIME_ID 2 47 + #define CLOCK_THREAD_CPUTIME_ID 3 48 + #define CLOCK_MONOTONIC_RAW 4 49 + #define CLOCK_REALTIME_COARSE 5 50 + #define CLOCK_MONOTONIC_COARSE 6 51 + #define CLOCK_BOOTTIME 7 52 + #define CLOCK_REALTIME_ALARM 8 53 + #define CLOCK_BOOTTIME_ALARM 9 54 + #define CLOCK_HWSPECIFIC 10 55 + #define CLOCK_TAI 11 56 + #define NR_CLOCKIDS 12 57 + 58 + 59 + #define NSEC_PER_SEC 1000000000ULL 60 + #define UNREASONABLE_LAT (NSEC_PER_SEC * 4) /* hopefully we resume in 4secs */ 61 + 62 + #define SUSPEND_SECS 15 63 + int alarmcount; 64 + int alarm_clock_id; 65 + struct timespec start_time; 66 + 67 + 68 + char *clockstring(int clockid) 69 + { 70 + switch (clockid) { 71 + case CLOCK_REALTIME: 72 + return "CLOCK_REALTIME"; 73 + case CLOCK_MONOTONIC: 74 + return "CLOCK_MONOTONIC"; 75 + case CLOCK_PROCESS_CPUTIME_ID: 76 + return "CLOCK_PROCESS_CPUTIME_ID"; 77 + case CLOCK_THREAD_CPUTIME_ID: 78 + return "CLOCK_THREAD_CPUTIME_ID"; 79 + case CLOCK_MONOTONIC_RAW: 80 + return "CLOCK_MONOTONIC_RAW"; 81 + case CLOCK_REALTIME_COARSE: 82 + return "CLOCK_REALTIME_COARSE"; 83 + case CLOCK_MONOTONIC_COARSE: 84 + return "CLOCK_MONOTONIC_COARSE"; 85 + case CLOCK_BOOTTIME: 86 + return "CLOCK_BOOTTIME"; 87 + case CLOCK_REALTIME_ALARM: 88 + return "CLOCK_REALTIME_ALARM"; 89 + case CLOCK_BOOTTIME_ALARM: 90 + return "CLOCK_BOOTTIME_ALARM"; 91 + case CLOCK_TAI: 92 + return "CLOCK_TAI"; 93 + }; 94 + return "UNKNOWN_CLOCKID"; 95 + } 96 + 97 + 98 + long long timespec_sub(struct timespec a, struct timespec b) 99 + { 100 + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; 101 + 102 + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; 103 + return ret; 104 + } 105 + 106 + int final_ret = 0; 107 + 108 + void sigalarm(int signo) 109 + { 110 + long long delta_ns; 111 + struct timespec ts; 112 + 113 + clock_gettime(alarm_clock_id, &ts); 114 + alarmcount++; 115 + 116 + delta_ns = timespec_sub(start_time, ts); 117 + delta_ns -= NSEC_PER_SEC * SUSPEND_SECS * alarmcount; 118 + 119 + printf("ALARM(%i): %ld:%ld latency: %lld ns ", alarmcount, ts.tv_sec, 120 + ts.tv_nsec, delta_ns); 121 + 122 + if (delta_ns > UNREASONABLE_LAT) { 123 + printf("[FAIL]\n"); 124 + final_ret = -1; 125 + } else 126 + printf("[OK]\n"); 127 + 128 + } 129 + 130 + int main(void) 131 + { 132 + timer_t tm1; 133 + struct itimerspec its1, its2; 134 + struct sigevent se; 135 + struct sigaction act; 136 + int signum = SIGRTMAX; 137 + 138 + /* Set up signal handler: */ 139 + sigfillset(&act.sa_mask); 140 + act.sa_flags = 0; 141 + act.sa_handler = sigalarm; 142 + sigaction(signum, &act, NULL); 143 + 144 + /* Set up timer: */ 145 + memset(&se, 0, sizeof(se)); 146 + se.sigev_notify = SIGEV_SIGNAL; 147 + se.sigev_signo = signum; 148 + se.sigev_value.sival_int = 0; 149 + 150 + for (alarm_clock_id = CLOCK_REALTIME_ALARM; 151 + alarm_clock_id <= CLOCK_BOOTTIME_ALARM; 152 + alarm_clock_id++) { 153 + 154 + alarmcount = 0; 155 + timer_create(alarm_clock_id, &se, &tm1); 156 + 157 + clock_gettime(alarm_clock_id, &start_time); 158 + printf("Start time (%s): %ld:%ld\n", clockstring(alarm_clock_id), 159 + start_time.tv_sec, start_time.tv_nsec); 160 + printf("Setting alarm for every %i seconds\n", SUSPEND_SECS); 161 + its1.it_value = start_time; 162 + its1.it_value.tv_sec += SUSPEND_SECS; 163 + its1.it_interval.tv_sec = SUSPEND_SECS; 164 + its1.it_interval.tv_nsec = 0; 165 + 166 + timer_settime(tm1, TIMER_ABSTIME, &its1, &its2); 167 + 168 + while (alarmcount < 5) 169 + sleep(1); /* First 5 alarms, do nothing */ 170 + 171 + printf("Starting suspend loops\n"); 172 + while (alarmcount < 10) { 173 + int ret; 174 + 175 + sleep(1); 176 + ret = system("echo mem > /sys/power/state"); 177 + if (ret) 178 + break; 179 + } 180 + timer_delete(tm1); 181 + } 182 + if (final_ret) 183 + return ksft_exit_fail(); 184 + return ksft_exit_pass(); 185 + }
+107
tools/testing/selftests/timers/change_skew.c
··· 1 + /* ADJ_FREQ Skew change test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2012 4 + * Licensed under the GPLv2 5 + * 6 + * NOTE: This is a meta-test which cranks the ADJ_FREQ knob and 7 + * then uses other tests to detect problems. Thus this test requires 8 + * that the raw_skew, inconsistency-check and nanosleep tests be 9 + * present in the same directory it is run from. 10 + * 11 + * To build: 12 + * $ gcc change_skew.c -o change_skew -lrt 13 + * 14 + * This program is free software: you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation, either version 2 of the License, or 17 + * (at your option) any later version. 18 + * 19 + * This program is distributed in the hope that it will be useful, 20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 + * GNU General Public License for more details. 23 + */ 24 + 25 + 26 + #include <stdio.h> 27 + #include <stdlib.h> 28 + #include <sys/time.h> 29 + #include <sys/timex.h> 30 + #include <time.h> 31 + #ifdef KTEST 32 + #include "../kselftest.h" 33 + #else 34 + static inline int ksft_exit_pass(void) 35 + { 36 + exit(0); 37 + } 38 + static inline int ksft_exit_fail(void) 39 + { 40 + exit(1); 41 + } 42 + #endif 43 + 44 + #define NSEC_PER_SEC 1000000000LL 45 + 46 + 47 + int change_skew_test(int ppm) 48 + { 49 + struct timex tx; 50 + int ret; 51 + 52 + tx.modes = ADJ_FREQUENCY; 53 + tx.freq = ppm << 16; 54 + 55 + ret = adjtimex(&tx); 56 + if (ret < 0) { 57 + printf("Error adjusting freq\n"); 58 + return ret; 59 + } 60 + 61 + ret = system("./raw_skew"); 62 + ret |= system("./inconsistency-check"); 63 + ret |= system("./nanosleep"); 64 + 65 + return ret; 66 + } 67 + 68 + 69 + int main(int argv, char **argc) 70 + { 71 + struct timex tx; 72 + int i, ret; 73 + 74 + int ppm[5] = {0, 250, 500, -250, -500}; 75 + 76 + /* Kill ntpd */ 77 + ret = system("killall -9 ntpd"); 78 + 79 + /* Make sure there's no offset adjustment going on */ 80 + tx.modes = ADJ_OFFSET; 81 + tx.offset = 0; 82 + ret = adjtimex(&tx); 83 + 84 + if (ret < 0) { 85 + printf("Maybe you're not running as root?\n"); 86 + return -1; 87 + } 88 + 89 + for (i = 0; i < 5; i++) { 90 + printf("Using %i ppm adjustment\n", ppm[i]); 91 + ret = change_skew_test(ppm[i]); 92 + if (ret) 93 + break; 94 + } 95 + 96 + /* Set things back */ 97 + tx.modes = ADJ_FREQUENCY; 98 + tx.offset = 0; 99 + adjtimex(&tx); 100 + 101 + if (ret) { 102 + printf("[FAIL]"); 103 + return ksft_exit_fail(); 104 + } 105 + printf("[OK]"); 106 + return ksft_exit_pass(); 107 + }
+179
tools/testing/selftests/timers/clocksource-switch.c
··· 1 + /* Clocksource change test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2012 4 + * Licensed under the GPLv2 5 + * 6 + * NOTE: This is a meta-test which quickly changes the clocksourc and 7 + * then uses other tests to detect problems. Thus this test requires 8 + * that the inconsistency-check and nanosleep tests be present in the 9 + * same directory it is run from. 10 + * 11 + * To build: 12 + * $ gcc clocksource-switch.c -o clocksource-switch -lrt 13 + * 14 + * This program is free software: you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation, either version 2 of the License, or 17 + * (at your option) any later version. 18 + * 19 + * This program is distributed in the hope that it will be useful, 20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 + * GNU General Public License for more details. 23 + */ 24 + 25 + 26 + #include <stdio.h> 27 + #include <unistd.h> 28 + #include <stdlib.h> 29 + #include <sys/time.h> 30 + #include <sys/timex.h> 31 + #include <time.h> 32 + #include <sys/types.h> 33 + #include <sys/stat.h> 34 + #include <fcntl.h> 35 + #include <string.h> 36 + #include <sys/wait.h> 37 + #ifdef KTEST 38 + #include "../kselftest.h" 39 + #else 40 + static inline int ksft_exit_pass(void) 41 + { 42 + exit(0); 43 + } 44 + static inline int ksft_exit_fail(void) 45 + { 46 + exit(1); 47 + } 48 + #endif 49 + 50 + 51 + int get_clocksources(char list[][30]) 52 + { 53 + int fd, i; 54 + size_t size; 55 + char buf[512]; 56 + char *head, *tmp; 57 + 58 + fd = open("/sys/devices/system/clocksource/clocksource0/available_clocksource", O_RDONLY); 59 + 60 + size = read(fd, buf, 512); 61 + 62 + close(fd); 63 + 64 + for (i = 0; i < 30; i++) 65 + list[i][0] = '\0'; 66 + 67 + head = buf; 68 + i = 0; 69 + while (head - buf < size) { 70 + /* Find the next space */ 71 + for (tmp = head; *tmp != ' '; tmp++) { 72 + if (*tmp == '\n') 73 + break; 74 + if (*tmp == '\0') 75 + break; 76 + } 77 + *tmp = '\0'; 78 + strcpy(list[i], head); 79 + head = tmp + 1; 80 + i++; 81 + } 82 + 83 + return i-1; 84 + } 85 + 86 + int get_cur_clocksource(char *buf, size_t size) 87 + { 88 + int fd; 89 + 90 + fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_RDONLY); 91 + 92 + size = read(fd, buf, size); 93 + 94 + return 0; 95 + } 96 + 97 + int change_clocksource(char *clocksource) 98 + { 99 + int fd; 100 + size_t size; 101 + 102 + fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY); 103 + 104 + if (fd < 0) 105 + return -1; 106 + 107 + size = write(fd, clocksource, strlen(clocksource)); 108 + 109 + if (size < 0) 110 + return -1; 111 + 112 + close(fd); 113 + return 0; 114 + } 115 + 116 + 117 + int run_tests(int secs) 118 + { 119 + int ret; 120 + char buf[255]; 121 + 122 + sprintf(buf, "./inconsistency-check -t %i", secs); 123 + ret = system(buf); 124 + if (ret) 125 + return ret; 126 + ret = system("./nanosleep"); 127 + return ret; 128 + } 129 + 130 + 131 + char clocksource_list[10][30]; 132 + 133 + int main(int argv, char **argc) 134 + { 135 + char orig_clk[512]; 136 + int count, i, status; 137 + pid_t pid; 138 + 139 + get_cur_clocksource(orig_clk, 512); 140 + 141 + count = get_clocksources(clocksource_list); 142 + 143 + if (change_clocksource(clocksource_list[0])) { 144 + printf("Error: You probably need to run this as root\n"); 145 + return -1; 146 + } 147 + 148 + /* Check everything is sane before we start switching asyncrhonously */ 149 + for (i = 0; i < count; i++) { 150 + printf("Validating clocksource %s\n", clocksource_list[i]); 151 + if (change_clocksource(clocksource_list[i])) { 152 + status = -1; 153 + goto out; 154 + } 155 + if (run_tests(5)) { 156 + status = -1; 157 + goto out; 158 + } 159 + } 160 + 161 + 162 + printf("Running Asyncrhonous Switching Tests...\n"); 163 + pid = fork(); 164 + if (!pid) 165 + return run_tests(60); 166 + 167 + while (pid != waitpid(pid, &status, WNOHANG)) 168 + for (i = 0; i < count; i++) 169 + if (change_clocksource(clocksource_list[i])) { 170 + status = -1; 171 + goto out; 172 + } 173 + out: 174 + change_clocksource(orig_clk); 175 + 176 + if (status) 177 + return ksft_exit_fail(); 178 + return ksft_exit_pass(); 179 + }
+204
tools/testing/selftests/timers/inconsistency-check.c
··· 1 + /* Time inconsistency check test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2003, 2004, 2005, 2012 4 + * (C) Copyright Linaro Limited 2015 5 + * Licensed under the GPLv2 6 + * 7 + * To build: 8 + * $ gcc inconsistency-check.c -o inconsistency-check -lrt 9 + * 10 + * This program is free software: you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation, either version 2 of the License, or 13 + * (at your option) any later version. 14 + * 15 + * This program is distributed in the hope that it will be useful, 16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 + * GNU General Public License for more details. 19 + */ 20 + 21 + 22 + 23 + #include <stdio.h> 24 + #include <unistd.h> 25 + #include <stdlib.h> 26 + #include <time.h> 27 + #include <sys/time.h> 28 + #include <sys/timex.h> 29 + #include <string.h> 30 + #include <signal.h> 31 + #ifdef KTEST 32 + #include "../kselftest.h" 33 + #else 34 + static inline int ksft_exit_pass(void) 35 + { 36 + exit(0); 37 + } 38 + static inline int ksft_exit_fail(void) 39 + { 40 + exit(1); 41 + } 42 + #endif 43 + 44 + #define CALLS_PER_LOOP 64 45 + #define NSEC_PER_SEC 1000000000ULL 46 + 47 + #define CLOCK_REALTIME 0 48 + #define CLOCK_MONOTONIC 1 49 + #define CLOCK_PROCESS_CPUTIME_ID 2 50 + #define CLOCK_THREAD_CPUTIME_ID 3 51 + #define CLOCK_MONOTONIC_RAW 4 52 + #define CLOCK_REALTIME_COARSE 5 53 + #define CLOCK_MONOTONIC_COARSE 6 54 + #define CLOCK_BOOTTIME 7 55 + #define CLOCK_REALTIME_ALARM 8 56 + #define CLOCK_BOOTTIME_ALARM 9 57 + #define CLOCK_HWSPECIFIC 10 58 + #define CLOCK_TAI 11 59 + #define NR_CLOCKIDS 12 60 + 61 + char *clockstring(int clockid) 62 + { 63 + switch (clockid) { 64 + case CLOCK_REALTIME: 65 + return "CLOCK_REALTIME"; 66 + case CLOCK_MONOTONIC: 67 + return "CLOCK_MONOTONIC"; 68 + case CLOCK_PROCESS_CPUTIME_ID: 69 + return "CLOCK_PROCESS_CPUTIME_ID"; 70 + case CLOCK_THREAD_CPUTIME_ID: 71 + return "CLOCK_THREAD_CPUTIME_ID"; 72 + case CLOCK_MONOTONIC_RAW: 73 + return "CLOCK_MONOTONIC_RAW"; 74 + case CLOCK_REALTIME_COARSE: 75 + return "CLOCK_REALTIME_COARSE"; 76 + case CLOCK_MONOTONIC_COARSE: 77 + return "CLOCK_MONOTONIC_COARSE"; 78 + case CLOCK_BOOTTIME: 79 + return "CLOCK_BOOTTIME"; 80 + case CLOCK_REALTIME_ALARM: 81 + return "CLOCK_REALTIME_ALARM"; 82 + case CLOCK_BOOTTIME_ALARM: 83 + return "CLOCK_BOOTTIME_ALARM"; 84 + case CLOCK_TAI: 85 + return "CLOCK_TAI"; 86 + }; 87 + return "UNKNOWN_CLOCKID"; 88 + } 89 + 90 + /* returns 1 if a <= b, 0 otherwise */ 91 + static inline int in_order(struct timespec a, struct timespec b) 92 + { 93 + /* use unsigned to avoid false positives on 2038 rollover */ 94 + if ((unsigned long)a.tv_sec < (unsigned long)b.tv_sec) 95 + return 1; 96 + if ((unsigned long)a.tv_sec > (unsigned long)b.tv_sec) 97 + return 0; 98 + if (a.tv_nsec > b.tv_nsec) 99 + return 0; 100 + return 1; 101 + } 102 + 103 + 104 + 105 + int consistency_test(int clock_type, unsigned long seconds) 106 + { 107 + struct timespec list[CALLS_PER_LOOP]; 108 + int i, inconsistent; 109 + long now, then; 110 + time_t t; 111 + char *start_str; 112 + 113 + clock_gettime(clock_type, &list[0]); 114 + now = then = list[0].tv_sec; 115 + 116 + /* timestamp start of test */ 117 + t = time(0); 118 + start_str = ctime(&t); 119 + 120 + while (seconds == -1 || now - then < seconds) { 121 + inconsistent = 0; 122 + 123 + /* Fill list */ 124 + for (i = 0; i < CALLS_PER_LOOP; i++) 125 + clock_gettime(clock_type, &list[i]); 126 + 127 + /* Check for inconsistencies */ 128 + for (i = 0; i < CALLS_PER_LOOP - 1; i++) 129 + if (!in_order(list[i], list[i+1])) 130 + inconsistent = i; 131 + 132 + /* display inconsistency */ 133 + if (inconsistent) { 134 + unsigned long long delta; 135 + 136 + printf("\%s\n", start_str); 137 + for (i = 0; i < CALLS_PER_LOOP; i++) { 138 + if (i == inconsistent) 139 + printf("--------------------\n"); 140 + printf("%lu:%lu\n", list[i].tv_sec, 141 + list[i].tv_nsec); 142 + if (i == inconsistent + 1) 143 + printf("--------------------\n"); 144 + } 145 + delta = list[inconsistent].tv_sec * NSEC_PER_SEC; 146 + delta += list[inconsistent].tv_nsec; 147 + delta -= list[inconsistent+1].tv_sec * NSEC_PER_SEC; 148 + delta -= list[inconsistent+1].tv_nsec; 149 + printf("Delta: %llu ns\n", delta); 150 + fflush(0); 151 + /* timestamp inconsistency*/ 152 + t = time(0); 153 + printf("%s\n", ctime(&t)); 154 + printf("[FAILED]\n"); 155 + return -1; 156 + } 157 + now = list[0].tv_sec; 158 + } 159 + printf("[OK]\n"); 160 + return 0; 161 + } 162 + 163 + 164 + int main(int argc, char *argv[]) 165 + { 166 + int clockid, opt; 167 + int userclock = CLOCK_REALTIME; 168 + int maxclocks = NR_CLOCKIDS; 169 + int runtime = 10; 170 + struct timespec ts; 171 + 172 + /* Process arguments */ 173 + while ((opt = getopt(argc, argv, "t:c:")) != -1) { 174 + switch (opt) { 175 + case 't': 176 + runtime = atoi(optarg); 177 + break; 178 + case 'c': 179 + userclock = atoi(optarg); 180 + maxclocks = userclock + 1; 181 + break; 182 + default: 183 + printf("Usage: %s [-t <secs>] [-c <clockid>]\n", argv[0]); 184 + printf(" -t: Number of seconds to run\n"); 185 + printf(" -c: clockid to use (default, all clockids)\n"); 186 + exit(-1); 187 + } 188 + } 189 + 190 + setbuf(stdout, NULL); 191 + 192 + for (clockid = userclock; clockid < maxclocks; clockid++) { 193 + 194 + if (clockid == CLOCK_HWSPECIFIC) 195 + continue; 196 + 197 + if (!clock_gettime(clockid, &ts)) { 198 + printf("Consistent %-30s ", clockstring(clockid)); 199 + if (consistency_test(clockid, runtime)) 200 + return ksft_exit_fail(); 201 + } 202 + } 203 + return ksft_exit_pass(); 204 + }
+319
tools/testing/selftests/timers/leap-a-day.c
··· 1 + /* Leap second stress test 2 + * by: John Stultz (john.stultz@linaro.org) 3 + * (C) Copyright IBM 2012 4 + * (C) Copyright 2013, 2015 Linaro Limited 5 + * Licensed under the GPLv2 6 + * 7 + * This test signals the kernel to insert a leap second 8 + * every day at midnight GMT. This allows for stessing the 9 + * kernel's leap-second behavior, as well as how well applications 10 + * handle the leap-second discontinuity. 11 + * 12 + * Usage: leap-a-day [-s] [-i <num>] 13 + * 14 + * Options: 15 + * -s: Each iteration, set the date to 10 seconds before midnight GMT. 16 + * This speeds up the number of leapsecond transitions tested, 17 + * but because it calls settimeofday frequently, advancing the 18 + * time by 24 hours every ~16 seconds, it may cause application 19 + * disruption. 20 + * 21 + * -i: Number of iterations to run (default: infinite) 22 + * 23 + * Other notes: Disabling NTP prior to running this is advised, as the two 24 + * may conflict in their commands to the kernel. 25 + * 26 + * To build: 27 + * $ gcc leap-a-day.c -o leap-a-day -lrt 28 + * 29 + * This program is free software: you can redistribute it and/or modify 30 + * it under the terms of the GNU General Public License as published by 31 + * the Free Software Foundation, either version 2 of the License, or 32 + * (at your option) any later version. 33 + * 34 + * This program is distributed in the hope that it will be useful, 35 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 + * GNU General Public License for more details. 38 + */ 39 + 40 + 41 + 42 + #include <stdio.h> 43 + #include <stdlib.h> 44 + #include <time.h> 45 + #include <sys/time.h> 46 + #include <sys/timex.h> 47 + #include <string.h> 48 + #include <signal.h> 49 + #include <unistd.h> 50 + #ifdef KTEST 51 + #include "../kselftest.h" 52 + #else 53 + static inline int ksft_exit_pass(void) 54 + { 55 + exit(0); 56 + } 57 + static inline int ksft_exit_fail(void) 58 + { 59 + exit(1); 60 + } 61 + #endif 62 + 63 + #define NSEC_PER_SEC 1000000000ULL 64 + #define CLOCK_TAI 11 65 + 66 + /* returns 1 if a <= b, 0 otherwise */ 67 + static inline int in_order(struct timespec a, struct timespec b) 68 + { 69 + if (a.tv_sec < b.tv_sec) 70 + return 1; 71 + if (a.tv_sec > b.tv_sec) 72 + return 0; 73 + if (a.tv_nsec > b.tv_nsec) 74 + return 0; 75 + return 1; 76 + } 77 + 78 + struct timespec timespec_add(struct timespec ts, unsigned long long ns) 79 + { 80 + ts.tv_nsec += ns; 81 + while (ts.tv_nsec >= NSEC_PER_SEC) { 82 + ts.tv_nsec -= NSEC_PER_SEC; 83 + ts.tv_sec++; 84 + } 85 + return ts; 86 + } 87 + 88 + char *time_state_str(int state) 89 + { 90 + switch (state) { 91 + case TIME_OK: return "TIME_OK"; 92 + case TIME_INS: return "TIME_INS"; 93 + case TIME_DEL: return "TIME_DEL"; 94 + case TIME_OOP: return "TIME_OOP"; 95 + case TIME_WAIT: return "TIME_WAIT"; 96 + case TIME_BAD: return "TIME_BAD"; 97 + } 98 + return "ERROR"; 99 + } 100 + 101 + /* clear NTP time_status & time_state */ 102 + int clear_time_state(void) 103 + { 104 + struct timex tx; 105 + int ret; 106 + 107 + /* 108 + * We have to call adjtime twice here, as kernels 109 + * prior to 6b1859dba01c7 (included in 3.5 and 110 + * -stable), had an issue with the state machine 111 + * and wouldn't clear the STA_INS/DEL flag directly. 112 + */ 113 + tx.modes = ADJ_STATUS; 114 + tx.status = STA_PLL; 115 + ret = adjtimex(&tx); 116 + 117 + /* Clear maxerror, as it can cause UNSYNC to be set */ 118 + tx.modes = ADJ_MAXERROR; 119 + tx.maxerror = 0; 120 + ret = adjtimex(&tx); 121 + 122 + /* Clear the status */ 123 + tx.modes = ADJ_STATUS; 124 + tx.status = 0; 125 + ret = adjtimex(&tx); 126 + 127 + return ret; 128 + } 129 + 130 + /* Make sure we cleanup on ctrl-c */ 131 + void handler(int unused) 132 + { 133 + clear_time_state(); 134 + exit(0); 135 + } 136 + 137 + /* Test for known hrtimer failure */ 138 + void test_hrtimer_failure(void) 139 + { 140 + struct timespec now, target; 141 + 142 + clock_gettime(CLOCK_REALTIME, &now); 143 + target = timespec_add(now, NSEC_PER_SEC/2); 144 + clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL); 145 + clock_gettime(CLOCK_REALTIME, &now); 146 + 147 + if (!in_order(target, now)) 148 + printf("ERROR: hrtimer early expiration failure observed.\n"); 149 + } 150 + 151 + int main(int argc, char **argv) 152 + { 153 + int settime = 0; 154 + int tai_time = 0; 155 + int insert = 1; 156 + int iterations = -1; 157 + int opt; 158 + 159 + /* Process arguments */ 160 + while ((opt = getopt(argc, argv, "sti:")) != -1) { 161 + switch (opt) { 162 + case 's': 163 + printf("Setting time to speed up testing\n"); 164 + settime = 1; 165 + break; 166 + case 'i': 167 + iterations = atoi(optarg); 168 + break; 169 + case 't': 170 + tai_time = 1; 171 + break; 172 + default: 173 + printf("Usage: %s [-s] [-i <iterations>]\n", argv[0]); 174 + printf(" -s: Set time to right before leap second each iteration\n"); 175 + printf(" -i: Number of iterations\n"); 176 + printf(" -t: Print TAI time\n"); 177 + exit(-1); 178 + } 179 + } 180 + 181 + /* Make sure TAI support is present if -t was used */ 182 + if (tai_time) { 183 + struct timespec ts; 184 + 185 + if (clock_gettime(CLOCK_TAI, &ts)) { 186 + printf("System doesn't support CLOCK_TAI\n"); 187 + ksft_exit_fail(); 188 + } 189 + } 190 + 191 + signal(SIGINT, handler); 192 + signal(SIGKILL, handler); 193 + 194 + if (iterations < 0) 195 + printf("This runs continuously. Press ctrl-c to stop\n"); 196 + else 197 + printf("Running for %i iterations. Press ctrl-c to stop\n", iterations); 198 + 199 + printf("\n"); 200 + while (1) { 201 + int ret; 202 + struct timespec ts; 203 + struct timex tx; 204 + time_t now, next_leap; 205 + 206 + /* Get the current time */ 207 + clock_gettime(CLOCK_REALTIME, &ts); 208 + 209 + /* Calculate the next possible leap second 23:59:60 GMT */ 210 + next_leap = ts.tv_sec; 211 + next_leap += 86400 - (next_leap % 86400); 212 + 213 + if (settime) { 214 + struct timeval tv; 215 + 216 + tv.tv_sec = next_leap - 10; 217 + tv.tv_usec = 0; 218 + settimeofday(&tv, NULL); 219 + printf("Setting time to %s", ctime(&tv.tv_sec)); 220 + } 221 + 222 + /* Reset NTP time state */ 223 + clear_time_state(); 224 + 225 + /* Set the leap second insert flag */ 226 + tx.modes = ADJ_STATUS; 227 + if (insert) 228 + tx.status = STA_INS; 229 + else 230 + tx.status = STA_DEL; 231 + ret = adjtimex(&tx); 232 + if (ret < 0) { 233 + printf("Error: Problem setting STA_INS/STA_DEL!: %s\n", 234 + time_state_str(ret)); 235 + return ksft_exit_fail(); 236 + } 237 + 238 + /* Validate STA_INS was set */ 239 + tx.modes = 0; 240 + ret = adjtimex(&tx); 241 + if (tx.status != STA_INS && tx.status != STA_DEL) { 242 + printf("Error: STA_INS/STA_DEL not set!: %s\n", 243 + time_state_str(ret)); 244 + return ksft_exit_fail(); 245 + } 246 + 247 + if (tai_time) { 248 + printf("Using TAI time," 249 + " no inconsistencies should be seen!\n"); 250 + } 251 + 252 + printf("Scheduling leap second for %s", ctime(&next_leap)); 253 + 254 + /* Wake up 3 seconds before leap */ 255 + ts.tv_sec = next_leap - 3; 256 + ts.tv_nsec = 0; 257 + 258 + while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL)) 259 + printf("Something woke us up, returning to sleep\n"); 260 + 261 + /* Validate STA_INS is still set */ 262 + tx.modes = 0; 263 + ret = adjtimex(&tx); 264 + if (tx.status != STA_INS && tx.status != STA_DEL) { 265 + printf("Something cleared STA_INS/STA_DEL, setting it again.\n"); 266 + tx.modes = ADJ_STATUS; 267 + if (insert) 268 + tx.status = STA_INS; 269 + else 270 + tx.status = STA_DEL; 271 + ret = adjtimex(&tx); 272 + } 273 + 274 + /* Check adjtimex output every half second */ 275 + now = tx.time.tv_sec; 276 + while (now < next_leap + 2) { 277 + char buf[26]; 278 + struct timespec tai; 279 + 280 + tx.modes = 0; 281 + ret = adjtimex(&tx); 282 + 283 + if (tai_time) { 284 + clock_gettime(CLOCK_TAI, &tai); 285 + printf("%ld sec, %9ld ns\t%s\n", 286 + tai.tv_sec, 287 + tai.tv_nsec, 288 + time_state_str(ret)); 289 + } else { 290 + ctime_r(&tx.time.tv_sec, buf); 291 + buf[strlen(buf)-1] = 0; /*remove trailing\n */ 292 + 293 + printf("%s + %6ld us (%i)\t%s\n", 294 + buf, 295 + tx.time.tv_usec, 296 + tx.tai, 297 + time_state_str(ret)); 298 + } 299 + now = tx.time.tv_sec; 300 + /* Sleep for another half second */ 301 + ts.tv_sec = 0; 302 + ts.tv_nsec = NSEC_PER_SEC / 2; 303 + clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); 304 + } 305 + /* Switch to using other mode */ 306 + insert = !insert; 307 + 308 + /* Note if kernel has known hrtimer failure */ 309 + test_hrtimer_failure(); 310 + 311 + printf("Leap complete\n\n"); 312 + 313 + if ((iterations != -1) && !(--iterations)) 314 + break; 315 + } 316 + 317 + clear_time_state(); 318 + return ksft_exit_pass(); 319 + }
+120
tools/testing/selftests/timers/leapcrash.c
··· 1 + /* Demo leapsecond deadlock 2 + * by: John Stultz (john.stultz@linaro.org) 3 + * (C) Copyright IBM 2012 4 + * (C) Copyright 2013, 2015 Linaro Limited 5 + * Licensed under the GPL 6 + * 7 + * This test demonstrates leapsecond deadlock that is possibe 8 + * on kernels from 2.6.26 to 3.3. 9 + * 10 + * WARNING: THIS WILL LIKELY HARDHANG SYSTEMS AND MAY LOSE DATA 11 + * RUN AT YOUR OWN RISK! 12 + * To build: 13 + * $ gcc leapcrash.c -o leapcrash -lrt 14 + */ 15 + 16 + 17 + 18 + #include <stdio.h> 19 + #include <stdlib.h> 20 + #include <time.h> 21 + #include <sys/time.h> 22 + #include <sys/timex.h> 23 + #include <string.h> 24 + #include <signal.h> 25 + #ifdef KTEST 26 + #include "../kselftest.h" 27 + #else 28 + static inline int ksft_exit_pass(void) 29 + { 30 + exit(0); 31 + } 32 + static inline int ksft_exit_fail(void) 33 + { 34 + exit(1); 35 + } 36 + #endif 37 + 38 + 39 + 40 + /* clear NTP time_status & time_state */ 41 + int clear_time_state(void) 42 + { 43 + struct timex tx; 44 + int ret; 45 + 46 + /* 47 + * We have to call adjtime twice here, as kernels 48 + * prior to 6b1859dba01c7 (included in 3.5 and 49 + * -stable), had an issue with the state machine 50 + * and wouldn't clear the STA_INS/DEL flag directly. 51 + */ 52 + tx.modes = ADJ_STATUS; 53 + tx.status = STA_PLL; 54 + ret = adjtimex(&tx); 55 + 56 + tx.modes = ADJ_STATUS; 57 + tx.status = 0; 58 + ret = adjtimex(&tx); 59 + 60 + return ret; 61 + } 62 + 63 + /* Make sure we cleanup on ctrl-c */ 64 + void handler(int unused) 65 + { 66 + clear_time_state(); 67 + exit(0); 68 + } 69 + 70 + 71 + int main(void) 72 + { 73 + struct timex tx; 74 + struct timespec ts; 75 + time_t next_leap; 76 + int count = 0; 77 + 78 + setbuf(stdout, NULL); 79 + 80 + signal(SIGINT, handler); 81 + signal(SIGKILL, handler); 82 + printf("This runs for a few minutes. Press ctrl-c to stop\n"); 83 + 84 + clear_time_state(); 85 + 86 + 87 + /* Get the current time */ 88 + clock_gettime(CLOCK_REALTIME, &ts); 89 + 90 + /* Calculate the next possible leap second 23:59:60 GMT */ 91 + next_leap = ts.tv_sec; 92 + next_leap += 86400 - (next_leap % 86400); 93 + 94 + for (count = 0; count < 20; count++) { 95 + struct timeval tv; 96 + 97 + 98 + /* set the time to 2 seconds before the leap */ 99 + tv.tv_sec = next_leap - 2; 100 + tv.tv_usec = 0; 101 + if (settimeofday(&tv, NULL)) { 102 + printf("Error: You're likely not running with proper (ie: root) permissions\n"); 103 + return ksft_exit_fail(); 104 + } 105 + tx.modes = 0; 106 + adjtimex(&tx); 107 + 108 + /* hammer on adjtime w/ STA_INS */ 109 + while (tx.time.tv_sec < next_leap + 1) { 110 + /* Set the leap second insert flag */ 111 + tx.modes = ADJ_STATUS; 112 + tx.status = STA_INS; 113 + adjtimex(&tx); 114 + } 115 + clear_time_state(); 116 + printf("."); 117 + } 118 + printf("[OK]\n"); 119 + return ksft_exit_pass(); 120 + }
+124
tools/testing/selftests/timers/mqueue-lat.c
··· 1 + /* Measure mqueue timeout latency 2 + * by: john stultz (john.stultz@linaro.org) 3 + * (C) Copyright Linaro 2013 4 + * 5 + * Inspired with permission from example test by: 6 + * Romain Francoise <romain@orebokech.com> 7 + * Licensed under the GPLv2 8 + * 9 + * To build: 10 + * $ gcc mqueue-lat.c -o mqueue-lat -lrt 11 + * 12 + * This program is free software: you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation, either version 2 of the License, or 15 + * (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + */ 22 + 23 + #include <stdio.h> 24 + #include <stdlib.h> 25 + #include <time.h> 26 + #include <sys/time.h> 27 + #include <sys/timex.h> 28 + #include <string.h> 29 + #include <signal.h> 30 + #include <errno.h> 31 + #include <mqueue.h> 32 + #ifdef KTEST 33 + #include "../kselftest.h" 34 + #else 35 + static inline int ksft_exit_pass(void) 36 + { 37 + exit(0); 38 + } 39 + static inline int ksft_exit_fail(void) 40 + { 41 + exit(1); 42 + } 43 + #endif 44 + 45 + #define NSEC_PER_SEC 1000000000ULL 46 + 47 + #define TARGET_TIMEOUT 100000000 /* 100ms in nanoseconds */ 48 + #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ 49 + 50 + 51 + long long timespec_sub(struct timespec a, struct timespec b) 52 + { 53 + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; 54 + 55 + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; 56 + return ret; 57 + } 58 + 59 + struct timespec timespec_add(struct timespec ts, unsigned long long ns) 60 + { 61 + ts.tv_nsec += ns; 62 + while (ts.tv_nsec >= NSEC_PER_SEC) { 63 + ts.tv_nsec -= NSEC_PER_SEC; 64 + ts.tv_sec++; 65 + } 66 + return ts; 67 + } 68 + 69 + int mqueue_lat_test(void) 70 + { 71 + 72 + mqd_t q; 73 + struct mq_attr attr; 74 + struct timespec start, end, now, target; 75 + int i, count, ret; 76 + 77 + q = mq_open("/foo", O_CREAT | O_RDONLY, 0666, NULL); 78 + if (q < 0) { 79 + perror("mq_open"); 80 + return -1; 81 + } 82 + mq_getattr(q, &attr); 83 + 84 + 85 + count = 100; 86 + clock_gettime(CLOCK_MONOTONIC, &start); 87 + 88 + for (i = 0; i < count; i++) { 89 + char buf[attr.mq_msgsize]; 90 + 91 + clock_gettime(CLOCK_REALTIME, &now); 92 + target = now; 93 + target = timespec_add(now, TARGET_TIMEOUT); /* 100ms */ 94 + 95 + ret = mq_timedreceive(q, buf, sizeof(buf), NULL, &target); 96 + if (ret < 0 && errno != ETIMEDOUT) { 97 + perror("mq_timedreceive"); 98 + return -1; 99 + } 100 + } 101 + clock_gettime(CLOCK_MONOTONIC, &end); 102 + 103 + mq_close(q); 104 + 105 + if ((timespec_sub(start, end)/count) > TARGET_TIMEOUT + UNRESONABLE_LATENCY) 106 + return -1; 107 + 108 + return 0; 109 + } 110 + 111 + int main(int argc, char **argv) 112 + { 113 + int ret; 114 + 115 + printf("Mqueue latency : "); 116 + 117 + ret = mqueue_lat_test(); 118 + if (ret < 0) { 119 + printf("[FAILED]\n"); 120 + return ksft_exit_fail(); 121 + } 122 + printf("[OK]\n"); 123 + return ksft_exit_pass(); 124 + }
+174
tools/testing/selftests/timers/nanosleep.c
··· 1 + /* Make sure timers don't return early 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * John Stultz (john.stultz@linaro.org) 4 + * (C) Copyright IBM 2012 5 + * (C) Copyright Linaro 2013 2015 6 + * Licensed under the GPLv2 7 + * 8 + * To build: 9 + * $ gcc nanosleep.c -o nanosleep -lrt 10 + * 11 + * This program is free software: you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License as published by 13 + * the Free Software Foundation, either version 2 of the License, or 14 + * (at your option) any later version. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + */ 21 + 22 + #include <stdio.h> 23 + #include <stdlib.h> 24 + #include <time.h> 25 + #include <sys/time.h> 26 + #include <sys/timex.h> 27 + #include <string.h> 28 + #include <signal.h> 29 + #ifdef KTEST 30 + #include "../kselftest.h" 31 + #else 32 + static inline int ksft_exit_pass(void) 33 + { 34 + exit(0); 35 + } 36 + static inline int ksft_exit_fail(void) 37 + { 38 + exit(1); 39 + } 40 + #endif 41 + 42 + #define NSEC_PER_SEC 1000000000ULL 43 + 44 + #define CLOCK_REALTIME 0 45 + #define CLOCK_MONOTONIC 1 46 + #define CLOCK_PROCESS_CPUTIME_ID 2 47 + #define CLOCK_THREAD_CPUTIME_ID 3 48 + #define CLOCK_MONOTONIC_RAW 4 49 + #define CLOCK_REALTIME_COARSE 5 50 + #define CLOCK_MONOTONIC_COARSE 6 51 + #define CLOCK_BOOTTIME 7 52 + #define CLOCK_REALTIME_ALARM 8 53 + #define CLOCK_BOOTTIME_ALARM 9 54 + #define CLOCK_HWSPECIFIC 10 55 + #define CLOCK_TAI 11 56 + #define NR_CLOCKIDS 12 57 + 58 + #define UNSUPPORTED 0xf00f 59 + 60 + char *clockstring(int clockid) 61 + { 62 + switch (clockid) { 63 + case CLOCK_REALTIME: 64 + return "CLOCK_REALTIME"; 65 + case CLOCK_MONOTONIC: 66 + return "CLOCK_MONOTONIC"; 67 + case CLOCK_PROCESS_CPUTIME_ID: 68 + return "CLOCK_PROCESS_CPUTIME_ID"; 69 + case CLOCK_THREAD_CPUTIME_ID: 70 + return "CLOCK_THREAD_CPUTIME_ID"; 71 + case CLOCK_MONOTONIC_RAW: 72 + return "CLOCK_MONOTONIC_RAW"; 73 + case CLOCK_REALTIME_COARSE: 74 + return "CLOCK_REALTIME_COARSE"; 75 + case CLOCK_MONOTONIC_COARSE: 76 + return "CLOCK_MONOTONIC_COARSE"; 77 + case CLOCK_BOOTTIME: 78 + return "CLOCK_BOOTTIME"; 79 + case CLOCK_REALTIME_ALARM: 80 + return "CLOCK_REALTIME_ALARM"; 81 + case CLOCK_BOOTTIME_ALARM: 82 + return "CLOCK_BOOTTIME_ALARM"; 83 + case CLOCK_TAI: 84 + return "CLOCK_TAI"; 85 + }; 86 + return "UNKNOWN_CLOCKID"; 87 + } 88 + 89 + /* returns 1 if a <= b, 0 otherwise */ 90 + static inline int in_order(struct timespec a, struct timespec b) 91 + { 92 + if (a.tv_sec < b.tv_sec) 93 + return 1; 94 + if (a.tv_sec > b.tv_sec) 95 + return 0; 96 + if (a.tv_nsec > b.tv_nsec) 97 + return 0; 98 + return 1; 99 + } 100 + 101 + struct timespec timespec_add(struct timespec ts, unsigned long long ns) 102 + { 103 + ts.tv_nsec += ns; 104 + while (ts.tv_nsec >= NSEC_PER_SEC) { 105 + ts.tv_nsec -= NSEC_PER_SEC; 106 + ts.tv_sec++; 107 + } 108 + return ts; 109 + } 110 + 111 + int nanosleep_test(int clockid, long long ns) 112 + { 113 + struct timespec now, target, rel; 114 + 115 + /* First check abs time */ 116 + if (clock_gettime(clockid, &now)) 117 + return UNSUPPORTED; 118 + target = timespec_add(now, ns); 119 + 120 + if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL)) 121 + return UNSUPPORTED; 122 + clock_gettime(clockid, &now); 123 + 124 + if (!in_order(target, now)) 125 + return -1; 126 + 127 + /* Second check reltime */ 128 + clock_gettime(clockid, &now); 129 + rel.tv_sec = 0; 130 + rel.tv_nsec = 0; 131 + rel = timespec_add(rel, ns); 132 + target = timespec_add(now, ns); 133 + clock_nanosleep(clockid, 0, &rel, NULL); 134 + clock_gettime(clockid, &now); 135 + 136 + if (!in_order(target, now)) 137 + return -1; 138 + return 0; 139 + } 140 + 141 + int main(int argc, char **argv) 142 + { 143 + long long length; 144 + int clockid, ret; 145 + 146 + for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { 147 + 148 + /* Skip cputime clockids since nanosleep won't increment cputime */ 149 + if (clockid == CLOCK_PROCESS_CPUTIME_ID || 150 + clockid == CLOCK_THREAD_CPUTIME_ID || 151 + clockid == CLOCK_HWSPECIFIC) 152 + continue; 153 + 154 + printf("Nanosleep %-31s ", clockstring(clockid)); 155 + 156 + length = 10; 157 + while (length <= (NSEC_PER_SEC * 10)) { 158 + ret = nanosleep_test(clockid, length); 159 + if (ret == UNSUPPORTED) { 160 + printf("[UNSUPPORTED]\n"); 161 + goto next; 162 + } 163 + if (ret < 0) { 164 + printf("[FAILED]\n"); 165 + return ksft_exit_fail(); 166 + } 167 + length *= 100; 168 + } 169 + printf("[OK]\n"); 170 + next: 171 + ret = 0; 172 + } 173 + return ksft_exit_pass(); 174 + }
+190
tools/testing/selftests/timers/nsleep-lat.c
··· 1 + /* Measure nanosleep timer latency 2 + * by: john stultz (john.stultz@linaro.org) 3 + * (C) Copyright Linaro 2013 4 + * Licensed under the GPLv2 5 + * 6 + * To build: 7 + * $ gcc nsleep-lat.c -o nsleep-lat -lrt 8 + * 9 + * This program is free software: you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation, either version 2 of the License, or 12 + * (at your option) any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + */ 19 + 20 + #include <stdio.h> 21 + #include <stdlib.h> 22 + #include <time.h> 23 + #include <sys/time.h> 24 + #include <sys/timex.h> 25 + #include <string.h> 26 + #include <signal.h> 27 + #ifdef KTEST 28 + #include "../kselftest.h" 29 + #else 30 + static inline int ksft_exit_pass(void) 31 + { 32 + exit(0); 33 + } 34 + static inline int ksft_exit_fail(void) 35 + { 36 + exit(1); 37 + } 38 + #endif 39 + 40 + #define NSEC_PER_SEC 1000000000ULL 41 + 42 + #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ 43 + 44 + 45 + #define CLOCK_REALTIME 0 46 + #define CLOCK_MONOTONIC 1 47 + #define CLOCK_PROCESS_CPUTIME_ID 2 48 + #define CLOCK_THREAD_CPUTIME_ID 3 49 + #define CLOCK_MONOTONIC_RAW 4 50 + #define CLOCK_REALTIME_COARSE 5 51 + #define CLOCK_MONOTONIC_COARSE 6 52 + #define CLOCK_BOOTTIME 7 53 + #define CLOCK_REALTIME_ALARM 8 54 + #define CLOCK_BOOTTIME_ALARM 9 55 + #define CLOCK_HWSPECIFIC 10 56 + #define CLOCK_TAI 11 57 + #define NR_CLOCKIDS 12 58 + 59 + #define UNSUPPORTED 0xf00f 60 + 61 + char *clockstring(int clockid) 62 + { 63 + switch (clockid) { 64 + case CLOCK_REALTIME: 65 + return "CLOCK_REALTIME"; 66 + case CLOCK_MONOTONIC: 67 + return "CLOCK_MONOTONIC"; 68 + case CLOCK_PROCESS_CPUTIME_ID: 69 + return "CLOCK_PROCESS_CPUTIME_ID"; 70 + case CLOCK_THREAD_CPUTIME_ID: 71 + return "CLOCK_THREAD_CPUTIME_ID"; 72 + case CLOCK_MONOTONIC_RAW: 73 + return "CLOCK_MONOTONIC_RAW"; 74 + case CLOCK_REALTIME_COARSE: 75 + return "CLOCK_REALTIME_COARSE"; 76 + case CLOCK_MONOTONIC_COARSE: 77 + return "CLOCK_MONOTONIC_COARSE"; 78 + case CLOCK_BOOTTIME: 79 + return "CLOCK_BOOTTIME"; 80 + case CLOCK_REALTIME_ALARM: 81 + return "CLOCK_REALTIME_ALARM"; 82 + case CLOCK_BOOTTIME_ALARM: 83 + return "CLOCK_BOOTTIME_ALARM"; 84 + case CLOCK_TAI: 85 + return "CLOCK_TAI"; 86 + }; 87 + return "UNKNOWN_CLOCKID"; 88 + } 89 + 90 + struct timespec timespec_add(struct timespec ts, unsigned long long ns) 91 + { 92 + ts.tv_nsec += ns; 93 + while (ts.tv_nsec >= NSEC_PER_SEC) { 94 + ts.tv_nsec -= NSEC_PER_SEC; 95 + ts.tv_sec++; 96 + } 97 + return ts; 98 + } 99 + 100 + 101 + long long timespec_sub(struct timespec a, struct timespec b) 102 + { 103 + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; 104 + 105 + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; 106 + return ret; 107 + } 108 + 109 + int nanosleep_lat_test(int clockid, long long ns) 110 + { 111 + struct timespec start, end, target; 112 + long long latency = 0; 113 + int i, count; 114 + 115 + target.tv_sec = ns/NSEC_PER_SEC; 116 + target.tv_nsec = ns%NSEC_PER_SEC; 117 + 118 + if (clock_gettime(clockid, &start)) 119 + return UNSUPPORTED; 120 + if (clock_nanosleep(clockid, 0, &target, NULL)) 121 + return UNSUPPORTED; 122 + 123 + count = 10; 124 + 125 + /* First check relative latency */ 126 + clock_gettime(clockid, &start); 127 + for (i = 0; i < count; i++) 128 + clock_nanosleep(clockid, 0, &target, NULL); 129 + clock_gettime(clockid, &end); 130 + 131 + if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) { 132 + printf("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns); 133 + return -1; 134 + } 135 + 136 + /* Next check absolute latency */ 137 + for (i = 0; i < count; i++) { 138 + clock_gettime(clockid, &start); 139 + target = timespec_add(start, ns); 140 + clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL); 141 + clock_gettime(clockid, &end); 142 + latency += timespec_sub(target, end); 143 + } 144 + 145 + if (latency/count > UNRESONABLE_LATENCY) { 146 + printf("Large abs latency: %lld ns :", latency/count); 147 + return -1; 148 + } 149 + 150 + return 0; 151 + } 152 + 153 + 154 + 155 + int main(int argc, char **argv) 156 + { 157 + long long length; 158 + int clockid, ret; 159 + 160 + for (clockid = CLOCK_REALTIME; clockid < NR_CLOCKIDS; clockid++) { 161 + 162 + /* Skip cputime clockids since nanosleep won't increment cputime */ 163 + if (clockid == CLOCK_PROCESS_CPUTIME_ID || 164 + clockid == CLOCK_THREAD_CPUTIME_ID || 165 + clockid == CLOCK_HWSPECIFIC) 166 + continue; 167 + 168 + printf("nsleep latency %-26s ", clockstring(clockid)); 169 + 170 + length = 10; 171 + while (length <= (NSEC_PER_SEC * 10)) { 172 + ret = nanosleep_lat_test(clockid, length); 173 + if (ret) 174 + break; 175 + length *= 100; 176 + 177 + } 178 + 179 + if (ret == UNSUPPORTED) { 180 + printf("[UNSUPPORTED]\n"); 181 + continue; 182 + } 183 + if (ret < 0) { 184 + printf("[FAILED]\n"); 185 + return ksft_exit_fail(); 186 + } 187 + printf("[OK]\n"); 188 + } 189 + return ksft_exit_pass(); 190 + }
+4 -5
tools/testing/selftests/timers/posix_timers.c
··· 35 35 static void kernel_loop(void) 36 36 { 37 37 void *addr = sbrk(0); 38 + int err = 0; 38 39 39 - while (!done) { 40 - brk(addr + 4096); 41 - brk(addr); 40 + while (!done && !err) { 41 + err = brk(addr + 4096); 42 + err |= brk(addr); 42 43 } 43 44 } 44 45 ··· 191 190 192 191 int main(int argc, char **argv) 193 192 { 194 - int err; 195 - 196 193 printf("Testing posix timers. False negative may happen on CPU execution \n"); 197 194 printf("based timers if other threads run on the CPU...\n"); 198 195
+154
tools/testing/selftests/timers/raw_skew.c
··· 1 + /* CLOCK_MONOTONIC vs CLOCK_MONOTONIC_RAW skew test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * John Stultz <john.stultz@linaro.org> 4 + * (C) Copyright IBM 2012 5 + * (C) Copyright Linaro Limited 2015 6 + * Licensed under the GPLv2 7 + * 8 + * To build: 9 + * $ gcc raw_skew.c -o raw_skew -lrt 10 + * 11 + * This program is free software: you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License as published by 13 + * the Free Software Foundation, either version 2 of the License, or 14 + * (at your option) any later version. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + */ 21 + 22 + #include <stdio.h> 23 + #include <unistd.h> 24 + #include <stdlib.h> 25 + #include <sys/time.h> 26 + #include <sys/timex.h> 27 + #include <time.h> 28 + #ifdef KTEST 29 + #include "../kselftest.h" 30 + #else 31 + static inline int ksft_exit_pass(void) 32 + { 33 + exit(0); 34 + } 35 + static inline int ksft_exit_fail(void) 36 + { 37 + exit(1); 38 + } 39 + #endif 40 + 41 + 42 + #define CLOCK_MONOTONIC_RAW 4 43 + #define NSEC_PER_SEC 1000000000LL 44 + 45 + #define shift_right(x, s) ({ \ 46 + __typeof__(x) __x = (x); \ 47 + __typeof__(s) __s = (s); \ 48 + __x < 0 ? -(-__x >> __s) : __x >> __s; \ 49 + }) 50 + 51 + long long llabs(long long val) 52 + { 53 + if (val < 0) 54 + val = -val; 55 + return val; 56 + } 57 + 58 + unsigned long long ts_to_nsec(struct timespec ts) 59 + { 60 + return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec; 61 + } 62 + 63 + struct timespec nsec_to_ts(long long ns) 64 + { 65 + struct timespec ts; 66 + 67 + ts.tv_sec = ns/NSEC_PER_SEC; 68 + ts.tv_nsec = ns%NSEC_PER_SEC; 69 + return ts; 70 + } 71 + 72 + long long diff_timespec(struct timespec start, struct timespec end) 73 + { 74 + long long start_ns, end_ns; 75 + 76 + start_ns = ts_to_nsec(start); 77 + end_ns = ts_to_nsec(end); 78 + return end_ns - start_ns; 79 + } 80 + 81 + void get_monotonic_and_raw(struct timespec *mon, struct timespec *raw) 82 + { 83 + struct timespec start, mid, end; 84 + long long diff = 0, tmp; 85 + int i; 86 + 87 + for (i = 0; i < 3; i++) { 88 + long long newdiff; 89 + 90 + clock_gettime(CLOCK_MONOTONIC, &start); 91 + clock_gettime(CLOCK_MONOTONIC_RAW, &mid); 92 + clock_gettime(CLOCK_MONOTONIC, &end); 93 + 94 + newdiff = diff_timespec(start, end); 95 + if (diff == 0 || newdiff < diff) { 96 + diff = newdiff; 97 + *raw = mid; 98 + tmp = (ts_to_nsec(start) + ts_to_nsec(end))/2; 99 + *mon = nsec_to_ts(tmp); 100 + } 101 + } 102 + } 103 + 104 + int main(int argv, char **argc) 105 + { 106 + struct timespec mon, raw, start, end; 107 + long long delta1, delta2, interval, eppm, ppm; 108 + struct timex tx1, tx2; 109 + 110 + setbuf(stdout, NULL); 111 + 112 + if (clock_gettime(CLOCK_MONOTONIC_RAW, &raw)) { 113 + printf("ERR: NO CLOCK_MONOTONIC_RAW\n"); 114 + return -1; 115 + } 116 + 117 + tx1.modes = 0; 118 + adjtimex(&tx1); 119 + get_monotonic_and_raw(&mon, &raw); 120 + start = mon; 121 + delta1 = diff_timespec(mon, raw); 122 + 123 + if (tx1.offset) 124 + printf("WARNING: ADJ_OFFSET in progress, this will cause inaccurate results\n"); 125 + 126 + printf("Estimating clock drift: "); 127 + sleep(120); 128 + 129 + get_monotonic_and_raw(&mon, &raw); 130 + end = mon; 131 + tx2.modes = 0; 132 + adjtimex(&tx2); 133 + delta2 = diff_timespec(mon, raw); 134 + 135 + interval = diff_timespec(start, end); 136 + 137 + /* calculate measured ppm between MONOTONIC and MONOTONIC_RAW */ 138 + eppm = ((delta2-delta1)*NSEC_PER_SEC)/interval; 139 + eppm = -eppm; 140 + printf("%lld.%i(est)", eppm/1000, abs((int)(eppm%1000))); 141 + 142 + /* Avg the two actual freq samples adjtimex gave us */ 143 + ppm = (tx1.freq + tx2.freq) * 1000 / 2; 144 + ppm = (long long)tx1.freq * 1000; 145 + ppm = shift_right(ppm, 16); 146 + printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); 147 + 148 + if (llabs(eppm - ppm) > 1000) { 149 + printf(" [FAILED]\n"); 150 + return ksft_exit_fail(); 151 + } 152 + printf(" [OK]\n"); 153 + return ksft_exit_pass(); 154 + }
+271
tools/testing/selftests/timers/rtctest.c
··· 1 + /* 2 + * Real Time Clock Driver Test/Example Program 3 + * 4 + * Compile with: 5 + * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest 6 + * 7 + * Copyright (C) 1996, Paul Gortmaker. 8 + * 9 + * Released under the GNU General Public License, version 2, 10 + * included herein by reference. 11 + * 12 + */ 13 + 14 + #include <stdio.h> 15 + #include <linux/rtc.h> 16 + #include <sys/ioctl.h> 17 + #include <sys/time.h> 18 + #include <sys/types.h> 19 + #include <fcntl.h> 20 + #include <unistd.h> 21 + #include <stdlib.h> 22 + #include <errno.h> 23 + 24 + 25 + /* 26 + * This expects the new RTC class driver framework, working with 27 + * clocks that will often not be clones of what the PC-AT had. 28 + * Use the command line to specify another RTC if you need one. 29 + */ 30 + static const char default_rtc[] = "/dev/rtc0"; 31 + 32 + 33 + int main(int argc, char **argv) 34 + { 35 + int i, fd, retval, irqcount = 0; 36 + unsigned long tmp, data; 37 + struct rtc_time rtc_tm; 38 + const char *rtc = default_rtc; 39 + struct timeval start, end, diff; 40 + 41 + switch (argc) { 42 + case 2: 43 + rtc = argv[1]; 44 + /* FALLTHROUGH */ 45 + case 1: 46 + break; 47 + default: 48 + fprintf(stderr, "usage: rtctest [rtcdev]\n"); 49 + return 1; 50 + } 51 + 52 + fd = open(rtc, O_RDONLY); 53 + 54 + if (fd == -1) { 55 + perror(rtc); 56 + exit(errno); 57 + } 58 + 59 + fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n"); 60 + 61 + /* Turn on update interrupts (one per second) */ 62 + retval = ioctl(fd, RTC_UIE_ON, 0); 63 + if (retval == -1) { 64 + if (errno == ENOTTY) { 65 + fprintf(stderr, 66 + "\n...Update IRQs not supported.\n"); 67 + goto test_READ; 68 + } 69 + perror("RTC_UIE_ON ioctl"); 70 + exit(errno); 71 + } 72 + 73 + fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:", 74 + rtc); 75 + fflush(stderr); 76 + for (i=1; i<6; i++) { 77 + /* This read will block */ 78 + retval = read(fd, &data, sizeof(unsigned long)); 79 + if (retval == -1) { 80 + perror("read"); 81 + exit(errno); 82 + } 83 + fprintf(stderr, " %d",i); 84 + fflush(stderr); 85 + irqcount++; 86 + } 87 + 88 + fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:"); 89 + fflush(stderr); 90 + for (i=1; i<6; i++) { 91 + struct timeval tv = {5, 0}; /* 5 second timeout on select */ 92 + fd_set readfds; 93 + 94 + FD_ZERO(&readfds); 95 + FD_SET(fd, &readfds); 96 + /* The select will wait until an RTC interrupt happens. */ 97 + retval = select(fd+1, &readfds, NULL, NULL, &tv); 98 + if (retval == -1) { 99 + perror("select"); 100 + exit(errno); 101 + } 102 + /* This read won't block unlike the select-less case above. */ 103 + retval = read(fd, &data, sizeof(unsigned long)); 104 + if (retval == -1) { 105 + perror("read"); 106 + exit(errno); 107 + } 108 + fprintf(stderr, " %d",i); 109 + fflush(stderr); 110 + irqcount++; 111 + } 112 + 113 + /* Turn off update interrupts */ 114 + retval = ioctl(fd, RTC_UIE_OFF, 0); 115 + if (retval == -1) { 116 + perror("RTC_UIE_OFF ioctl"); 117 + exit(errno); 118 + } 119 + 120 + test_READ: 121 + /* Read the RTC time/date */ 122 + retval = ioctl(fd, RTC_RD_TIME, &rtc_tm); 123 + if (retval == -1) { 124 + perror("RTC_RD_TIME ioctl"); 125 + exit(errno); 126 + } 127 + 128 + fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n", 129 + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, 130 + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); 131 + 132 + /* Set the alarm to 5 sec in the future, and check for rollover */ 133 + rtc_tm.tm_sec += 5; 134 + if (rtc_tm.tm_sec >= 60) { 135 + rtc_tm.tm_sec %= 60; 136 + rtc_tm.tm_min++; 137 + } 138 + if (rtc_tm.tm_min == 60) { 139 + rtc_tm.tm_min = 0; 140 + rtc_tm.tm_hour++; 141 + } 142 + if (rtc_tm.tm_hour == 24) 143 + rtc_tm.tm_hour = 0; 144 + 145 + retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); 146 + if (retval == -1) { 147 + if (errno == ENOTTY) { 148 + fprintf(stderr, 149 + "\n...Alarm IRQs not supported.\n"); 150 + goto test_PIE; 151 + } 152 + perror("RTC_ALM_SET ioctl"); 153 + exit(errno); 154 + } 155 + 156 + /* Read the current alarm settings */ 157 + retval = ioctl(fd, RTC_ALM_READ, &rtc_tm); 158 + if (retval == -1) { 159 + perror("RTC_ALM_READ ioctl"); 160 + exit(errno); 161 + } 162 + 163 + fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", 164 + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); 165 + 166 + /* Enable alarm interrupts */ 167 + retval = ioctl(fd, RTC_AIE_ON, 0); 168 + if (retval == -1) { 169 + perror("RTC_AIE_ON ioctl"); 170 + exit(errno); 171 + } 172 + 173 + fprintf(stderr, "Waiting 5 seconds for alarm..."); 174 + fflush(stderr); 175 + /* This blocks until the alarm ring causes an interrupt */ 176 + retval = read(fd, &data, sizeof(unsigned long)); 177 + if (retval == -1) { 178 + perror("read"); 179 + exit(errno); 180 + } 181 + irqcount++; 182 + fprintf(stderr, " okay. Alarm rang.\n"); 183 + 184 + /* Disable alarm interrupts */ 185 + retval = ioctl(fd, RTC_AIE_OFF, 0); 186 + if (retval == -1) { 187 + perror("RTC_AIE_OFF ioctl"); 188 + exit(errno); 189 + } 190 + 191 + test_PIE: 192 + /* Read periodic IRQ rate */ 193 + retval = ioctl(fd, RTC_IRQP_READ, &tmp); 194 + if (retval == -1) { 195 + /* not all RTCs support periodic IRQs */ 196 + if (errno == ENOTTY) { 197 + fprintf(stderr, "\nNo periodic IRQ support\n"); 198 + goto done; 199 + } 200 + perror("RTC_IRQP_READ ioctl"); 201 + exit(errno); 202 + } 203 + fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp); 204 + 205 + fprintf(stderr, "Counting 20 interrupts at:"); 206 + fflush(stderr); 207 + 208 + /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */ 209 + for (tmp=2; tmp<=64; tmp*=2) { 210 + 211 + retval = ioctl(fd, RTC_IRQP_SET, tmp); 212 + if (retval == -1) { 213 + /* not all RTCs can change their periodic IRQ rate */ 214 + if (errno == ENOTTY) { 215 + fprintf(stderr, 216 + "\n...Periodic IRQ rate is fixed\n"); 217 + goto done; 218 + } 219 + perror("RTC_IRQP_SET ioctl"); 220 + exit(errno); 221 + } 222 + 223 + fprintf(stderr, "\n%ldHz:\t", tmp); 224 + fflush(stderr); 225 + 226 + /* Enable periodic interrupts */ 227 + retval = ioctl(fd, RTC_PIE_ON, 0); 228 + if (retval == -1) { 229 + perror("RTC_PIE_ON ioctl"); 230 + exit(errno); 231 + } 232 + 233 + for (i=1; i<21; i++) { 234 + gettimeofday(&start, NULL); 235 + /* This blocks */ 236 + retval = read(fd, &data, sizeof(unsigned long)); 237 + if (retval == -1) { 238 + perror("read"); 239 + exit(errno); 240 + } 241 + gettimeofday(&end, NULL); 242 + timersub(&end, &start, &diff); 243 + if (diff.tv_sec > 0 || 244 + diff.tv_usec > ((1000000L / tmp) * 1.10)) { 245 + fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n", 246 + diff.tv_sec, diff.tv_usec, 247 + (1000000L / tmp)); 248 + fflush(stdout); 249 + exit(-1); 250 + } 251 + 252 + fprintf(stderr, " %d",i); 253 + fflush(stderr); 254 + irqcount++; 255 + } 256 + 257 + /* Disable periodic interrupts */ 258 + retval = ioctl(fd, RTC_PIE_OFF, 0); 259 + if (retval == -1) { 260 + perror("RTC_PIE_OFF ioctl"); 261 + exit(errno); 262 + } 263 + } 264 + 265 + done: 266 + fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n"); 267 + 268 + close(fd); 269 + 270 + return 0; 271 + }
+144
tools/testing/selftests/timers/set-2038.c
··· 1 + /* Time bounds setting test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2012 4 + * Licensed under the GPLv2 5 + * 6 + * NOTE: This is a meta-test which sets the time to edge cases then 7 + * uses other tests to detect problems. Thus this test requires that 8 + * the inconsistency-check and nanosleep tests be present in the same 9 + * directory it is run from. 10 + * 11 + * To build: 12 + * $ gcc set-2038.c -o set-2038 -lrt 13 + * 14 + * This program is free software: you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation, either version 2 of the License, or 17 + * (at your option) any later version. 18 + * 19 + * This program is distributed in the hope that it will be useful, 20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 + * GNU General Public License for more details. 23 + */ 24 + 25 + #include <stdio.h> 26 + #include <stdlib.h> 27 + #include <unistd.h> 28 + #include <time.h> 29 + #include <sys/time.h> 30 + #ifdef KTEST 31 + #include "../kselftest.h" 32 + #else 33 + static inline int ksft_exit_pass(void) 34 + { 35 + exit(0); 36 + } 37 + static inline int ksft_exit_fail(void) 38 + { 39 + exit(1); 40 + } 41 + #endif 42 + 43 + #define NSEC_PER_SEC 1000000000LL 44 + 45 + #define KTIME_MAX ((long long)~((unsigned long long)1 << 63)) 46 + #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) 47 + 48 + #define YEAR_1901 (-0x7fffffffL) 49 + #define YEAR_1970 1 50 + #define YEAR_2038 0x7fffffffL /*overflows 32bit time_t */ 51 + #define YEAR_2262 KTIME_SEC_MAX /*overflows 64bit ktime_t */ 52 + #define YEAR_MAX ((long long)((1ULL<<63)-1)) /*overflows 64bit time_t */ 53 + 54 + int is32bits(void) 55 + { 56 + return (sizeof(long) == 4); 57 + } 58 + 59 + int settime(long long time) 60 + { 61 + struct timeval now; 62 + int ret; 63 + 64 + now.tv_sec = (time_t)time; 65 + now.tv_usec = 0; 66 + 67 + ret = settimeofday(&now, NULL); 68 + 69 + printf("Setting time to 0x%lx: %d\n", (long)time, ret); 70 + return ret; 71 + } 72 + 73 + int do_tests(void) 74 + { 75 + int ret; 76 + 77 + ret = system("date"); 78 + ret = system("./inconsistency-check -c 0 -t 20"); 79 + ret |= system("./nanosleep"); 80 + ret |= system("./nsleep-lat"); 81 + return ret; 82 + 83 + } 84 + 85 + int main(int argc, char *argv[]) 86 + { 87 + int ret = 0; 88 + int opt, dangerous = 0; 89 + time_t start; 90 + 91 + /* Process arguments */ 92 + while ((opt = getopt(argc, argv, "d")) != -1) { 93 + switch (opt) { 94 + case 'd': 95 + dangerous = 1; 96 + } 97 + } 98 + 99 + start = time(0); 100 + 101 + /* First test that crazy values don't work */ 102 + if (!settime(YEAR_1901)) { 103 + ret = -1; 104 + goto out; 105 + } 106 + if (!settime(YEAR_MAX)) { 107 + ret = -1; 108 + goto out; 109 + } 110 + if (!is32bits() && !settime(YEAR_2262)) { 111 + ret = -1; 112 + goto out; 113 + } 114 + 115 + /* Now test behavior near edges */ 116 + settime(YEAR_1970); 117 + ret = do_tests(); 118 + if (ret) 119 + goto out; 120 + 121 + settime(YEAR_2038 - 600); 122 + ret = do_tests(); 123 + if (ret) 124 + goto out; 125 + 126 + /* The rest of the tests can blowup on 32bit systems */ 127 + if (is32bits() && !dangerous) 128 + goto out; 129 + /* Test rollover behavior 32bit edge */ 130 + settime(YEAR_2038 - 10); 131 + ret = do_tests(); 132 + if (ret) 133 + goto out; 134 + 135 + settime(YEAR_2262 - 600); 136 + ret = do_tests(); 137 + 138 + out: 139 + /* restore clock */ 140 + settime(start); 141 + if (ret) 142 + return ksft_exit_fail(); 143 + return ksft_exit_pass(); 144 + }
+79
tools/testing/selftests/timers/set-tai.c
··· 1 + /* Set tai offset 2 + * by: John Stultz <john.stultz@linaro.org> 3 + * (C) Copyright Linaro 2013 4 + * Licensed under the GPLv2 5 + * 6 + * This program is free software: you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation, either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + 18 + #include <stdio.h> 19 + #include <stdlib.h> 20 + #include <time.h> 21 + #include <sys/time.h> 22 + #include <sys/timex.h> 23 + #include <string.h> 24 + #include <signal.h> 25 + #include <unistd.h> 26 + #ifdef KTEST 27 + #include "../kselftest.h" 28 + #else 29 + static inline int ksft_exit_pass(void) 30 + { 31 + exit(0); 32 + } 33 + static inline int ksft_exit_fail(void) 34 + { 35 + exit(1); 36 + } 37 + #endif 38 + 39 + int set_tai(int offset) 40 + { 41 + struct timex tx; 42 + 43 + memset(&tx, 0, sizeof(tx)); 44 + 45 + tx.modes = ADJ_TAI; 46 + tx.constant = offset; 47 + 48 + return adjtimex(&tx); 49 + } 50 + 51 + int get_tai(void) 52 + { 53 + struct timex tx; 54 + 55 + memset(&tx, 0, sizeof(tx)); 56 + 57 + adjtimex(&tx); 58 + return tx.tai; 59 + } 60 + 61 + int main(int argc, char **argv) 62 + { 63 + int i, ret; 64 + 65 + ret = get_tai(); 66 + printf("tai offset started at %i\n", ret); 67 + 68 + printf("Checking tai offsets can be properly set: "); 69 + for (i = 1; i <= 60; i++) { 70 + ret = set_tai(i); 71 + ret = get_tai(); 72 + if (ret != i) { 73 + printf("[FAILED] expected: %i got %i\n", i, ret); 74 + return ksft_exit_fail(); 75 + } 76 + } 77 + printf("[OK]\n"); 78 + return ksft_exit_pass(); 79 + }
+216
tools/testing/selftests/timers/set-timer-lat.c
··· 1 + /* set_timer latency test 2 + * John Stultz (john.stultz@linaro.org) 3 + * (C) Copyright Linaro 2014 4 + * Licensed under the GPLv2 5 + * 6 + * This test makes sure the set_timer api is correct 7 + * 8 + * To build: 9 + * $ gcc set-timer-lat.c -o set-timer-lat -lrt 10 + * 11 + * This program is free software: you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License as published by 13 + * the Free Software Foundation, either version 2 of the License, or 14 + * (at your option) any later version. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + */ 21 + 22 + 23 + #include <stdio.h> 24 + #include <unistd.h> 25 + #include <time.h> 26 + #include <string.h> 27 + #include <signal.h> 28 + #include <stdlib.h> 29 + #include <pthread.h> 30 + #ifdef KTEST 31 + #include "../kselftest.h" 32 + #else 33 + static inline int ksft_exit_pass(void) 34 + { 35 + exit(0); 36 + } 37 + static inline int ksft_exit_fail(void) 38 + { 39 + exit(1); 40 + } 41 + #endif 42 + 43 + #define CLOCK_REALTIME 0 44 + #define CLOCK_MONOTONIC 1 45 + #define CLOCK_PROCESS_CPUTIME_ID 2 46 + #define CLOCK_THREAD_CPUTIME_ID 3 47 + #define CLOCK_MONOTONIC_RAW 4 48 + #define CLOCK_REALTIME_COARSE 5 49 + #define CLOCK_MONOTONIC_COARSE 6 50 + #define CLOCK_BOOTTIME 7 51 + #define CLOCK_REALTIME_ALARM 8 52 + #define CLOCK_BOOTTIME_ALARM 9 53 + #define CLOCK_HWSPECIFIC 10 54 + #define CLOCK_TAI 11 55 + #define NR_CLOCKIDS 12 56 + 57 + 58 + #define NSEC_PER_SEC 1000000000ULL 59 + #define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ 60 + 61 + #define TIMER_SECS 1 62 + int alarmcount; 63 + int clock_id; 64 + struct timespec start_time; 65 + long long max_latency_ns; 66 + 67 + char *clockstring(int clockid) 68 + { 69 + switch (clockid) { 70 + case CLOCK_REALTIME: 71 + return "CLOCK_REALTIME"; 72 + case CLOCK_MONOTONIC: 73 + return "CLOCK_MONOTONIC"; 74 + case CLOCK_PROCESS_CPUTIME_ID: 75 + return "CLOCK_PROCESS_CPUTIME_ID"; 76 + case CLOCK_THREAD_CPUTIME_ID: 77 + return "CLOCK_THREAD_CPUTIME_ID"; 78 + case CLOCK_MONOTONIC_RAW: 79 + return "CLOCK_MONOTONIC_RAW"; 80 + case CLOCK_REALTIME_COARSE: 81 + return "CLOCK_REALTIME_COARSE"; 82 + case CLOCK_MONOTONIC_COARSE: 83 + return "CLOCK_MONOTONIC_COARSE"; 84 + case CLOCK_BOOTTIME: 85 + return "CLOCK_BOOTTIME"; 86 + case CLOCK_REALTIME_ALARM: 87 + return "CLOCK_REALTIME_ALARM"; 88 + case CLOCK_BOOTTIME_ALARM: 89 + return "CLOCK_BOOTTIME_ALARM"; 90 + case CLOCK_TAI: 91 + return "CLOCK_TAI"; 92 + }; 93 + return "UNKNOWN_CLOCKID"; 94 + } 95 + 96 + 97 + long long timespec_sub(struct timespec a, struct timespec b) 98 + { 99 + long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; 100 + 101 + ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; 102 + return ret; 103 + } 104 + 105 + 106 + void sigalarm(int signo) 107 + { 108 + long long delta_ns; 109 + struct timespec ts; 110 + 111 + clock_gettime(clock_id, &ts); 112 + alarmcount++; 113 + 114 + delta_ns = timespec_sub(start_time, ts); 115 + delta_ns -= NSEC_PER_SEC * TIMER_SECS * alarmcount; 116 + 117 + if (delta_ns < 0) 118 + printf("%s timer fired early: FAIL\n", clockstring(clock_id)); 119 + 120 + if (delta_ns > max_latency_ns) 121 + max_latency_ns = delta_ns; 122 + } 123 + 124 + int do_timer(int clock_id, int flags) 125 + { 126 + struct sigevent se; 127 + timer_t tm1; 128 + struct itimerspec its1, its2; 129 + int err; 130 + 131 + /* Set up timer: */ 132 + memset(&se, 0, sizeof(se)); 133 + se.sigev_notify = SIGEV_SIGNAL; 134 + se.sigev_signo = SIGRTMAX; 135 + se.sigev_value.sival_int = 0; 136 + 137 + max_latency_ns = 0; 138 + alarmcount = 0; 139 + 140 + err = timer_create(clock_id, &se, &tm1); 141 + if (err) { 142 + if ((clock_id == CLOCK_REALTIME_ALARM) || 143 + (clock_id == CLOCK_BOOTTIME_ALARM)) { 144 + printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", 145 + clockstring(clock_id), 146 + flags ? "ABSTIME":"RELTIME"); 147 + return 0; 148 + } 149 + printf("%s - timer_create() failed\n", clockstring(clock_id)); 150 + return -1; 151 + } 152 + 153 + clock_gettime(clock_id, &start_time); 154 + if (flags) { 155 + its1.it_value = start_time; 156 + its1.it_value.tv_sec += TIMER_SECS; 157 + } else { 158 + its1.it_value.tv_sec = TIMER_SECS; 159 + its1.it_value.tv_nsec = 0; 160 + } 161 + its1.it_interval.tv_sec = TIMER_SECS; 162 + its1.it_interval.tv_nsec = 0; 163 + 164 + err = timer_settime(tm1, flags, &its1, &its2); 165 + if (err) { 166 + printf("%s - timer_settime() failed\n", clockstring(clock_id)); 167 + return -1; 168 + } 169 + 170 + while (alarmcount < 5) 171 + sleep(1); 172 + 173 + printf("%-22s %s max latency: %10lld ns : ", 174 + clockstring(clock_id), 175 + flags ? "ABSTIME":"RELTIME", 176 + max_latency_ns); 177 + 178 + timer_delete(tm1); 179 + if (max_latency_ns < UNRESONABLE_LATENCY) { 180 + printf("[OK]\n"); 181 + return 0; 182 + } 183 + printf("[FAILED]\n"); 184 + return -1; 185 + } 186 + 187 + int main(void) 188 + { 189 + struct sigaction act; 190 + int signum = SIGRTMAX; 191 + int ret = 0; 192 + 193 + /* Set up signal handler: */ 194 + sigfillset(&act.sa_mask); 195 + act.sa_flags = 0; 196 + act.sa_handler = sigalarm; 197 + sigaction(signum, &act, NULL); 198 + 199 + printf("Setting timers for every %i seconds\n", TIMER_SECS); 200 + for (clock_id = 0; clock_id < NR_CLOCKIDS; clock_id++) { 201 + 202 + if ((clock_id == CLOCK_PROCESS_CPUTIME_ID) || 203 + (clock_id == CLOCK_THREAD_CPUTIME_ID) || 204 + (clock_id == CLOCK_MONOTONIC_RAW) || 205 + (clock_id == CLOCK_REALTIME_COARSE) || 206 + (clock_id == CLOCK_MONOTONIC_COARSE) || 207 + (clock_id == CLOCK_HWSPECIFIC)) 208 + continue; 209 + 210 + ret |= do_timer(clock_id, TIMER_ABSTIME); 211 + ret |= do_timer(clock_id, 0); 212 + } 213 + if (ret) 214 + return ksft_exit_fail(); 215 + return ksft_exit_pass(); 216 + }
+89
tools/testing/selftests/timers/skew_consistency.c
··· 1 + /* ADJ_FREQ Skew consistency test 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2012 4 + * Licensed under the GPLv2 5 + * 6 + * NOTE: This is a meta-test which cranks the ADJ_FREQ knob back 7 + * and forth and watches for consistency problems. Thus this test requires 8 + * that the inconsistency-check tests be present in the same directory it 9 + * is run from. 10 + * 11 + * To build: 12 + * $ gcc skew_consistency.c -o skew_consistency -lrt 13 + * 14 + * This program is free software: you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation, either version 2 of the License, or 17 + * (at your option) any later version. 18 + * 19 + * This program is distributed in the hope that it will be useful, 20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 + * GNU General Public License for more details. 23 + */ 24 + 25 + 26 + #include <stdio.h> 27 + #include <stdlib.h> 28 + #include <unistd.h> 29 + #include <sys/time.h> 30 + #include <sys/timex.h> 31 + #include <time.h> 32 + #include <sys/types.h> 33 + #include <sys/stat.h> 34 + #include <fcntl.h> 35 + #include <stdlib.h> 36 + #include <string.h> 37 + #include <sys/wait.h> 38 + #ifdef KTEST 39 + #include "../kselftest.h" 40 + #else 41 + static inline int ksft_exit_pass(void) 42 + { 43 + exit(0); 44 + } 45 + static inline int ksft_exit_fail(void) 46 + { 47 + exit(1); 48 + } 49 + #endif 50 + 51 + #define NSEC_PER_SEC 1000000000LL 52 + 53 + int main(int argv, char **argc) 54 + { 55 + struct timex tx; 56 + int ret, ppm; 57 + pid_t pid; 58 + 59 + 60 + printf("Running Asyncrhonous Frequency Changing Tests...\n"); 61 + 62 + pid = fork(); 63 + if (!pid) 64 + return system("./inconsistency-check -c 1 -t 600"); 65 + 66 + ppm = 500; 67 + ret = 0; 68 + 69 + while (pid != waitpid(pid, &ret, WNOHANG)) { 70 + ppm = -ppm; 71 + tx.modes = ADJ_FREQUENCY; 72 + tx.freq = ppm << 16; 73 + adjtimex(&tx); 74 + usleep(500000); 75 + } 76 + 77 + /* Set things back */ 78 + tx.modes = ADJ_FREQUENCY; 79 + tx.offset = 0; 80 + adjtimex(&tx); 81 + 82 + 83 + if (ret) { 84 + printf("[FAILED]\n"); 85 + return ksft_exit_fail(); 86 + } 87 + printf("[OK]\n"); 88 + return ksft_exit_pass(); 89 + }
+204
tools/testing/selftests/timers/threadtest.c
··· 1 + /* threadtest.c 2 + * by: john stultz (johnstul@us.ibm.com) 3 + * (C) Copyright IBM 2004, 2005, 2006, 2012 4 + * Licensed under the GPLv2 5 + * 6 + * To build: 7 + * $ gcc threadtest.c -o threadtest -lrt 8 + * 9 + * This program is free software: you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation, either version 2 of the License, or 12 + * (at your option) any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + */ 19 + #include <stdio.h> 20 + #include <unistd.h> 21 + #include <stdlib.h> 22 + #include <sys/time.h> 23 + #include <pthread.h> 24 + #ifdef KTEST 25 + #include "../kselftest.h" 26 + #else 27 + static inline int ksft_exit_pass(void) 28 + { 29 + exit(0); 30 + } 31 + static inline int ksft_exit_fail(void) 32 + { 33 + exit(1); 34 + } 35 + #endif 36 + 37 + 38 + /* serializes shared list access */ 39 + pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; 40 + /* serializes console output */ 41 + pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; 42 + 43 + 44 + #define MAX_THREADS 128 45 + #define LISTSIZE 128 46 + 47 + int done = 0; 48 + 49 + struct timespec global_list[LISTSIZE]; 50 + int listcount = 0; 51 + 52 + 53 + void checklist(struct timespec *list, int size) 54 + { 55 + int i, j; 56 + struct timespec *a, *b; 57 + 58 + /* scan the list */ 59 + for (i = 0; i < size-1; i++) { 60 + a = &list[i]; 61 + b = &list[i+1]; 62 + 63 + /* look for any time inconsistencies */ 64 + if ((b->tv_sec <= a->tv_sec) && 65 + (b->tv_nsec < a->tv_nsec)) { 66 + 67 + /* flag other threads */ 68 + done = 1; 69 + 70 + /*serialize printing to avoid junky output*/ 71 + pthread_mutex_lock(&print_lock); 72 + 73 + /* dump the list */ 74 + printf("\n"); 75 + for (j = 0; j < size; j++) { 76 + if (j == i) 77 + printf("---------------\n"); 78 + printf("%lu:%lu\n", list[j].tv_sec, list[j].tv_nsec); 79 + if (j == i+1) 80 + printf("---------------\n"); 81 + } 82 + printf("[FAILED]\n"); 83 + 84 + pthread_mutex_unlock(&print_lock); 85 + } 86 + } 87 + } 88 + 89 + /* The shared thread shares a global list 90 + * that each thread fills while holding the lock. 91 + * This stresses clock syncronization across cpus. 92 + */ 93 + void *shared_thread(void *arg) 94 + { 95 + while (!done) { 96 + /* protect the list */ 97 + pthread_mutex_lock(&list_lock); 98 + 99 + /* see if we're ready to check the list */ 100 + if (listcount >= LISTSIZE) { 101 + checklist(global_list, LISTSIZE); 102 + listcount = 0; 103 + } 104 + clock_gettime(CLOCK_MONOTONIC, &global_list[listcount++]); 105 + 106 + pthread_mutex_unlock(&list_lock); 107 + } 108 + return NULL; 109 + } 110 + 111 + 112 + /* Each independent thread fills in its own 113 + * list. This stresses clock_gettime() lock contention. 114 + */ 115 + void *independent_thread(void *arg) 116 + { 117 + struct timespec my_list[LISTSIZE]; 118 + int count; 119 + 120 + while (!done) { 121 + /* fill the list */ 122 + for (count = 0; count < LISTSIZE; count++) 123 + clock_gettime(CLOCK_MONOTONIC, &my_list[count]); 124 + checklist(my_list, LISTSIZE); 125 + } 126 + return NULL; 127 + } 128 + 129 + #define DEFAULT_THREAD_COUNT 8 130 + #define DEFAULT_RUNTIME 30 131 + 132 + int main(int argc, char **argv) 133 + { 134 + int thread_count, i; 135 + time_t start, now, runtime; 136 + char buf[255]; 137 + pthread_t pth[MAX_THREADS]; 138 + int opt; 139 + void *tret; 140 + int ret = 0; 141 + void *(*thread)(void *) = shared_thread; 142 + 143 + thread_count = DEFAULT_THREAD_COUNT; 144 + runtime = DEFAULT_RUNTIME; 145 + 146 + /* Process arguments */ 147 + while ((opt = getopt(argc, argv, "t:n:i")) != -1) { 148 + switch (opt) { 149 + case 't': 150 + runtime = atoi(optarg); 151 + break; 152 + case 'n': 153 + thread_count = atoi(optarg); 154 + break; 155 + case 'i': 156 + thread = independent_thread; 157 + printf("using independent threads\n"); 158 + break; 159 + default: 160 + printf("Usage: %s [-t <secs>] [-n <numthreads>] [-i]\n", argv[0]); 161 + printf(" -t: time to run\n"); 162 + printf(" -n: number of threads\n"); 163 + printf(" -i: use independent threads\n"); 164 + return -1; 165 + } 166 + } 167 + 168 + if (thread_count > MAX_THREADS) 169 + thread_count = MAX_THREADS; 170 + 171 + 172 + setbuf(stdout, NULL); 173 + 174 + start = time(0); 175 + strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&start)); 176 + printf("%s\n", buf); 177 + printf("Testing consistency with %i threads for %ld seconds: ", thread_count, runtime); 178 + 179 + /* spawn */ 180 + for (i = 0; i < thread_count; i++) 181 + pthread_create(&pth[i], 0, thread, 0); 182 + 183 + while (time(&now) < start + runtime) { 184 + sleep(1); 185 + if (done) { 186 + ret = 1; 187 + strftime(buf, 255, "%a, %d %b %Y %T %z", localtime(&now)); 188 + printf("%s\n", buf); 189 + goto out; 190 + } 191 + } 192 + printf("[OK]\n"); 193 + done = 1; 194 + 195 + out: 196 + /* wait */ 197 + for (i = 0; i < thread_count; i++) 198 + pthread_join(pth[i], &tret); 199 + 200 + /* die */ 201 + if (ret) 202 + ksft_exit_fail(); 203 + return ksft_exit_pass(); 204 + }
+202
tools/testing/selftests/timers/valid-adjtimex.c
··· 1 + /* valid adjtimex test 2 + * by: John Stultz <john.stultz@linaro.org> 3 + * (C) Copyright Linaro 2015 4 + * Licensed under the GPLv2 5 + * 6 + * This test validates adjtimex interface with valid 7 + * and invalid test data. 8 + * 9 + * Usage: valid-adjtimex 10 + * 11 + * To build: 12 + * $ gcc valid-adjtimex.c -o valid-adjtimex -lrt 13 + * 14 + * This program is free software: you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation, either version 2 of the License, or 17 + * (at your option) any later version. 18 + * 19 + * This program is distributed in the hope that it will be useful, 20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 + * GNU General Public License for more details. 23 + */ 24 + 25 + 26 + 27 + #include <stdio.h> 28 + #include <stdlib.h> 29 + #include <time.h> 30 + #include <sys/time.h> 31 + #include <sys/timex.h> 32 + #include <string.h> 33 + #include <signal.h> 34 + #include <unistd.h> 35 + #ifdef KTEST 36 + #include "../kselftest.h" 37 + #else 38 + static inline int ksft_exit_pass(void) 39 + { 40 + exit(0); 41 + } 42 + static inline int ksft_exit_fail(void) 43 + { 44 + exit(1); 45 + } 46 + #endif 47 + 48 + #define NSEC_PER_SEC 1000000000L 49 + 50 + /* clear NTP time_status & time_state */ 51 + int clear_time_state(void) 52 + { 53 + struct timex tx; 54 + int ret; 55 + 56 + tx.modes = ADJ_STATUS; 57 + tx.status = 0; 58 + ret = adjtimex(&tx); 59 + return ret; 60 + } 61 + 62 + #define NUM_FREQ_VALID 32 63 + #define NUM_FREQ_OUTOFRANGE 4 64 + #define NUM_FREQ_INVALID 2 65 + 66 + long valid_freq[NUM_FREQ_VALID] = { 67 + -499<<16, 68 + -450<<16, 69 + -400<<16, 70 + -350<<16, 71 + -300<<16, 72 + -250<<16, 73 + -200<<16, 74 + -150<<16, 75 + -100<<16, 76 + -75<<16, 77 + -50<<16, 78 + -25<<16, 79 + -10<<16, 80 + -5<<16, 81 + -1<<16, 82 + -1000, 83 + 1<<16, 84 + 5<<16, 85 + 10<<16, 86 + 25<<16, 87 + 50<<16, 88 + 75<<16, 89 + 100<<16, 90 + 150<<16, 91 + 200<<16, 92 + 250<<16, 93 + 300<<16, 94 + 350<<16, 95 + 400<<16, 96 + 450<<16, 97 + 499<<16, 98 + }; 99 + 100 + long outofrange_freq[NUM_FREQ_OUTOFRANGE] = { 101 + -1000<<16, 102 + -550<<16, 103 + 550<<16, 104 + 1000<<16, 105 + }; 106 + 107 + #define LONG_MAX (~0UL>>1) 108 + #define LONG_MIN (-LONG_MAX - 1) 109 + 110 + long invalid_freq[NUM_FREQ_INVALID] = { 111 + LONG_MAX, 112 + LONG_MIN, 113 + }; 114 + 115 + int validate_freq(void) 116 + { 117 + struct timex tx; 118 + int ret, pass = 0; 119 + int i; 120 + 121 + clear_time_state(); 122 + 123 + memset(&tx, 0, sizeof(struct timex)); 124 + /* Set the leap second insert flag */ 125 + 126 + printf("Testing ADJ_FREQ... "); 127 + for (i = 0; i < NUM_FREQ_VALID; i++) { 128 + tx.modes = ADJ_FREQUENCY; 129 + tx.freq = valid_freq[i]; 130 + 131 + ret = adjtimex(&tx); 132 + if (ret < 0) { 133 + printf("[FAIL]\n"); 134 + printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", 135 + valid_freq[i], valid_freq[i]>>16); 136 + pass = -1; 137 + goto out; 138 + } 139 + tx.modes = 0; 140 + ret = adjtimex(&tx); 141 + if (tx.freq != valid_freq[i]) { 142 + printf("Warning: freq value %ld not what we set it (%ld)!\n", 143 + tx.freq, valid_freq[i]); 144 + } 145 + } 146 + for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) { 147 + tx.modes = ADJ_FREQUENCY; 148 + tx.freq = outofrange_freq[i]; 149 + 150 + ret = adjtimex(&tx); 151 + if (ret < 0) { 152 + printf("[FAIL]\n"); 153 + printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n", 154 + outofrange_freq[i], outofrange_freq[i]>>16); 155 + pass = -1; 156 + goto out; 157 + } 158 + tx.modes = 0; 159 + ret = adjtimex(&tx); 160 + if (tx.freq == outofrange_freq[i]) { 161 + printf("[FAIL]\n"); 162 + printf("ERROR: out of range value %ld actually set!\n", 163 + tx.freq); 164 + pass = -1; 165 + goto out; 166 + } 167 + } 168 + 169 + 170 + if (sizeof(long) == 8) { /* this case only applies to 64bit systems */ 171 + for (i = 0; i < NUM_FREQ_INVALID; i++) { 172 + tx.modes = ADJ_FREQUENCY; 173 + tx.freq = invalid_freq[i]; 174 + ret = adjtimex(&tx); 175 + if (ret >= 0) { 176 + printf("[FAIL]\n"); 177 + printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n", 178 + invalid_freq[i]); 179 + pass = -1; 180 + goto out; 181 + } 182 + } 183 + } 184 + 185 + printf("[OK]\n"); 186 + out: 187 + /* reset freq to zero */ 188 + tx.modes = ADJ_FREQUENCY; 189 + tx.freq = 0; 190 + ret = adjtimex(&tx); 191 + 192 + return pass; 193 + } 194 + 195 + 196 + int main(int argc, char **argv) 197 + { 198 + if (validate_freq()) 199 + return ksft_exit_fail(); 200 + 201 + return ksft_exit_pass(); 202 + }
+3 -2
tools/testing/selftests/user/Makefile
··· 3 3 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 4 4 all: 5 5 6 - run_tests: all 7 - ./test_user_copy.sh 6 + TEST_PROGS := test_user_copy.sh 7 + 8 + include ../lib.mk
+4 -3
tools/testing/selftests/vm/Makefile
··· 1 1 # Makefile for vm selftests 2 2 3 - CC = $(CROSS_COMPILE)gcc 4 3 CFLAGS = -Wall 5 4 BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest 6 5 BINARIES += transhuge-stress ··· 8 9 %: %.c 9 10 $(CC) $(CFLAGS) -o $@ $^ -lrt 10 11 11 - run_tests: all 12 - @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1) 12 + TEST_PROGS := run_vmtests 13 + TEST_FILES := $(BINARIES) 14 + 15 + include ../lib.mk 13 16 14 17 clean: 15 18 $(RM) $(BINARIES)
tools/testing/selftests/vm/run_vmtests