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

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

Pull Kselftest updates from Shuah Khan:
"Several fixes and enhancements to existing tests and a few new tests:

- add new amd-pstate tests and fix and enhance existing ones

- add new watchdog tests and enhance existing ones to improve
coverage

- fixes to ftrace, splice_read, rtc, and efivars tests

- fixes to handle egrep obsolescence in the latest grep release

- miscellaneous spelling and SPDX fixes"

* tag 'linux-kselftest-next-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (24 commits)
selftests/ftrace: Use long for synthetic event probe test
selftests/tpm2: Split async tests call to separate shell script runner
selftests: splice_read: Fix sysfs read cases
selftests: ftrace: Use "grep -E" instead of "egrep"
selftests: gpio: Use "grep -E" instead of "egrep"
selftests: kselftest_deps: Use "grep -E" instead of "egrep"
selftests/efivarfs: Add checking of the test return value
cpufreq: amd-pstate: fix spdxcheck warnings for amd-pstate-ut.c
selftests: rtc: skip when RTC is not present
selftests/ftrace: event_triggers: wait longer for test_event_enable
selftests/vDSO: Add riscv getcpu & gettimeofday test
Documentation: amd-pstate: Add tbench and gitsource test introduction
selftests: amd-pstate: Trigger gitsource benchmark and test cpus
selftests: amd-pstate: Trigger tbench benchmark and test cpus
selftests: amd-pstate: Split basic.sh into run.sh and basic.sh.
selftests: amd-pstate: Rename amd-pstate-ut.sh to basic.sh.
selftests/ftrace: Convert tracer tests to use 'requires' to specify program dependency
selftests/ftrace: Add check for ping command for trigger tests
selftests/watchdog: Fix spelling mistake "Temeprature" -> "Temperature"
selftests/watchdog: add test for WDIOC_GETTEMP
...

+1500 -119
+172 -18
Documentation/admin-guide/pm/amd-pstate.rst
··· 405 405 406 406 1. Test case decriptions 407 407 408 + 1). Basic tests 409 + 410 + Test prerequisite and basic functions for the ``amd-pstate`` driver. 411 + 408 412 +---------+--------------------------------+------------------------------------------------------------------------------------+ 409 413 | Index | Functions | Description | 410 414 +=========+================================+====================================================================================+ 411 - | 0 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. | 415 + | 1 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. | 412 416 | | || | 413 417 | | || The detail refer to `Processor Support <processor_support_>`_. | 414 418 +---------+--------------------------------+------------------------------------------------------------------------------------+ 415 - | 1 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. | 419 + | 2 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. | 416 420 | | || | 417 421 | | || AMD P-States and ACPI hardware P-States always can be supported in one processor. | 418 422 | | | But AMD P-States has the higher priority and if it is enabled with | 419 423 | | | :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond to the | 420 424 | | | request from AMD P-States. | 421 425 +---------+--------------------------------+------------------------------------------------------------------------------------+ 422 - | 2 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. | 426 + | 3 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. | 423 427 | | || highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0. | 424 428 +---------+--------------------------------+------------------------------------------------------------------------------------+ 425 - | 3 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode | 429 + | 4 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode | 426 430 | | | are reasonable. | 427 431 | | || max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 | 428 432 | | || If boost is not active but supported, this maximum frequency will be larger than | 429 433 | | | the one in ``cpuinfo``. | 430 434 +---------+--------------------------------+------------------------------------------------------------------------------------+ 431 435 436 + 2). Tbench test 437 + 438 + Test and monitor the cpu changes when running tbench benchmark under the specified governor. 439 + These changes include desire performance, frequency, load, performance, energy etc. 440 + The specified governor is ondemand or schedutil. 441 + Tbench can also be tested on the ``acpi-cpufreq`` kernel driver for comparison. 442 + 443 + 3). Gitsource test 444 + 445 + Test and monitor the cpu changes when running gitsource benchmark under the specified governor. 446 + These changes include desire performance, frequency, load, time, energy etc. 447 + The specified governor is ondemand or schedutil. 448 + Gitsource can also be tested on the ``acpi-cpufreq`` kernel driver for comparison. 449 + 432 450 #. How to execute the tests 433 451 434 452 We use test module in the kselftest frameworks to implement it. 435 - We create amd-pstate-ut module and tie it into kselftest.(for 453 + We create ``amd-pstate-ut`` module and tie it into kselftest.(for 436 454 details refer to Linux Kernel Selftests [4]_). 437 455 438 - 1. Build 456 + 1). Build 439 457 440 458 + open the :c:macro:`CONFIG_X86_AMD_PSTATE` configuration option. 441 459 + set the :c:macro:`CONFIG_X86_AMD_PSTATE_UT` configuration option to M. ··· 463 445 $ cd linux 464 446 $ make -C tools/testing/selftests 465 447 466 - #. Installation & Steps :: 448 + + make perf :: 449 + 450 + $ cd tools/perf/ 451 + $ make 452 + 453 + 454 + 2). Installation & Steps :: 467 455 468 456 $ make -C tools/testing/selftests install INSTALL_PATH=~/kselftest 457 + $ cp tools/perf/perf /usr/bin/perf 469 458 $ sudo ./kselftest/run_kselftest.sh -c amd-pstate 470 - TAP version 13 471 - 1..1 472 - # selftests: amd-pstate: amd-pstate-ut.sh 473 - # amd-pstate-ut: ok 474 - ok 1 selftests: amd-pstate: amd-pstate-ut.sh 475 459 476 - #. Results :: 460 + 3). Specified test case :: 477 461 478 - $ dmesg | grep "amd_pstate_ut" | tee log.txt 479 - [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success! 480 - [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success! 481 - [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success! 482 - [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success! 462 + $ cd ~/kselftest/amd-pstate 463 + $ sudo ./run.sh -t basic 464 + $ sudo ./run.sh -t tbench 465 + $ sudo ./run.sh -t tbench -m acpi-cpufreq 466 + $ sudo ./run.sh -t gitsource 467 + $ sudo ./run.sh -t gitsource -m acpi-cpufreq 468 + $ ./run.sh --help 469 + ./run.sh: illegal option -- - 470 + Usage: ./run.sh [OPTION...] 471 + [-h <help>] 472 + [-o <output-file-for-dump>] 473 + [-c <all: All testing, 474 + basic: Basic testing, 475 + tbench: Tbench testing, 476 + gitsource: Gitsource testing.>] 477 + [-t <tbench time limit>] 478 + [-p <tbench process number>] 479 + [-l <loop times for tbench>] 480 + [-i <amd tracer interval>] 481 + [-m <comparative test: acpi-cpufreq>] 482 + 483 + 484 + 4). Results 485 + 486 + + basic 487 + 488 + When you finish test, you will get the following log info :: 489 + 490 + $ dmesg | grep "amd_pstate_ut" | tee log.txt 491 + [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success! 492 + [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success! 493 + [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success! 494 + [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success! 495 + 496 + + tbench 497 + 498 + When you finish test, you will get selftest.tbench.csv and png images. 499 + The selftest.tbench.csv file contains the raw data and the drop of the comparative test. 500 + The png images shows the performance, energy and performan per watt of each test. 501 + Open selftest.tbench.csv : 502 + 503 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 504 + + Governor | Round | Des-perf | Freq | Load | Performance | Energy | Performance Per Watt | 505 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 506 + + Unit | | | GHz | | MB/s | J | MB/J | 507 + +=================================================+==============+==========+=========+==========+=============+=========+======================+ 508 + + amd-pstate-ondemand | 1 | | | | 2504.05 | 1563.67 | 158.5378 | 509 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 510 + + amd-pstate-ondemand | 2 | | | | 2243.64 | 1430.32 | 155.2941 | 511 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 512 + + amd-pstate-ondemand | 3 | | | | 2183.88 | 1401.32 | 154.2860 | 513 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 514 + + amd-pstate-ondemand | Average | | | | 2310.52 | 1465.1 | 156.1268 | 515 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 516 + + amd-pstate-schedutil | 1 | 165.329 | 1.62257 | 99.798 | 2136.54 | 1395.26 | 151.5971 | 517 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 518 + + amd-pstate-schedutil | 2 | 166 | 1.49761 | 99.9993 | 2100.56 | 1380.5 | 150.6377 | 519 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 520 + + amd-pstate-schedutil | 3 | 166 | 1.47806 | 99.9993 | 2084.12 | 1375.76 | 149.9737 | 521 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 522 + + amd-pstate-schedutil | Average | 165.776 | 1.53275 | 99.9322 | 2107.07 | 1383.84 | 150.7399 | 523 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 524 + + acpi-cpufreq-ondemand | 1 | | | | 2529.9 | 1564.4 | 160.0997 | 525 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 526 + + acpi-cpufreq-ondemand | 2 | | | | 2249.76 | 1432.97 | 155.4297 | 527 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 528 + + acpi-cpufreq-ondemand | 3 | | | | 2181.46 | 1406.88 | 153.5060 | 529 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 530 + + acpi-cpufreq-ondemand | Average | | | | 2320.37 | 1468.08 | 156.4741 | 531 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 532 + + acpi-cpufreq-schedutil | 1 | | | | 2137.64 | 1385.24 | 152.7723 | 533 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 534 + + acpi-cpufreq-schedutil | 2 | | | | 2107.05 | 1372.23 | 152.0138 | 535 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 536 + + acpi-cpufreq-schedutil | 3 | | | | 2085.86 | 1365.35 | 151.2433 | 537 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 538 + + acpi-cpufreq-schedutil | Average | | | | 2110.18 | 1374.27 | 152.0136 | 539 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 540 + + acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil | Comprison(%) | | | | -9.0584 | -6.3899 | -2.8506 | 541 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 542 + + amd-pstate-ondemand VS amd-pstate-schedutil | Comprison(%) | | | | 8.8053 | -5.5463 | -3.4503 | 543 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 544 + + acpi-cpufreq-ondemand VS amd-pstate-ondemand | Comprison(%) | | | | -0.4245 | -0.2029 | -0.2219 | 545 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 546 + + acpi-cpufreq-schedutil VS amd-pstate-schedutil | Comprison(%) | | | | -0.1473 | 0.6963 | -0.8378 | 547 + +-------------------------------------------------+--------------+----------+---------+----------+-------------+---------+----------------------+ 548 + 549 + + gitsource 550 + 551 + When you finish test, you will get selftest.gitsource.csv and png images. 552 + The selftest.gitsource.csv file contains the raw data and the drop of the comparative test. 553 + The png images shows the performance, energy and performan per watt of each test. 554 + Open selftest.gitsource.csv : 555 + 556 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 557 + + Governor | Round | Des-perf | Freq | Load | Time | Energy | Performance Per Watt | 558 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 559 + + Unit | | | GHz | | s | J | 1/J | 560 + +=================================================+==============+==========+==========+==========+=============+=========+======================+ 561 + + amd-pstate-ondemand | 1 | 50.119 | 2.10509 | 23.3076 | 475.69 | 865.78 | 0.001155027 | 562 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 563 + + amd-pstate-ondemand | 2 | 94.8006 | 1.98771 | 56.6533 | 467.1 | 839.67 | 0.001190944 | 564 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 565 + + amd-pstate-ondemand | 3 | 76.6091 | 2.53251 | 43.7791 | 467.69 | 855.85 | 0.001168429 | 566 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 567 + + amd-pstate-ondemand | Average | 73.8429 | 2.20844 | 41.2467 | 470.16 | 853.767 | 0.001171279 | 568 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 569 + + amd-pstate-schedutil | 1 | 165.919 | 1.62319 | 98.3868 | 464.17 | 866.8 | 0.001153668 | 570 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 571 + + amd-pstate-schedutil | 2 | 165.97 | 1.31309 | 99.5712 | 480.15 | 880.4 | 0.001135847 | 572 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 573 + + amd-pstate-schedutil | 3 | 165.973 | 1.28448 | 99.9252 | 481.79 | 867.02 | 0.001153375 | 574 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 575 + + amd-pstate-schedutil | Average | 165.954 | 1.40692 | 99.2944 | 475.37 | 871.407 | 0.001147569 | 576 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 577 + + acpi-cpufreq-ondemand | 1 | | | | 2379.62 | 742.96 | 0.001345967 | 578 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 579 + + acpi-cpufreq-ondemand | 2 | | | | 441.74 | 817.49 | 0.001223256 | 580 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 581 + + acpi-cpufreq-ondemand | 3 | | | | 455.48 | 820.01 | 0.001219497 | 582 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 583 + + acpi-cpufreq-ondemand | Average | | | | 425.613 | 793.487 | 0.001260260 | 584 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 585 + + acpi-cpufreq-schedutil | 1 | | | | 459.69 | 838.54 | 0.001192548 | 586 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 587 + + acpi-cpufreq-schedutil | 2 | | | | 466.55 | 830.89 | 0.001203528 | 588 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 589 + + acpi-cpufreq-schedutil | 3 | | | | 470.38 | 837.32 | 0.001194286 | 590 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 591 + + acpi-cpufreq-schedutil | Average | | | | 465.54 | 835.583 | 0.001196769 | 592 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 593 + + acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil | Comprison(%) | | | | 9.3810 | 5.3051 | -5.0379 | 594 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 595 + + amd-pstate-ondemand VS amd-pstate-schedutil | Comprison(%) | 124.7392 | -36.2934 | 140.7329 | 1.1081 | 2.0661 | -2.0242 | 596 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 597 + + acpi-cpufreq-ondemand VS amd-pstate-ondemand | Comprison(%) | | | | 10.4665 | 7.5968 | -7.0605 | 598 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 599 + + acpi-cpufreq-schedutil VS amd-pstate-schedutil | Comprison(%) | | | | 2.1115 | 4.2873 | -4.1110 | 600 + +-------------------------------------------------+--------------+----------+----------+----------+-------------+---------+----------------------+ 483 601 484 602 Reference 485 603 ===========
+1 -1
drivers/cpufreq/amd-pstate-ut.c
··· 1 - // SPDX-License-Identifier: GPL-1.0-or-later 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 3 * AMD Processor P-state Frequency Driver Unit Test 4 4 *
+10 -1
tools/testing/selftests/amd-pstate/Makefile
··· 4 4 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 5 5 all: 6 6 7 - TEST_PROGS := amd-pstate-ut.sh 7 + uname_M := $(shell uname -m 2>/dev/null || echo not) 8 + ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) 9 + 10 + ifeq (x86,$(ARCH)) 11 + TEST_GEN_FILES += ../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py 12 + TEST_GEN_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py 13 + endif 14 + 15 + TEST_PROGS := run.sh 16 + TEST_FILES := basic.sh tbench.sh gitsource.sh 8 17 9 18 include ../lib.mk
-56
tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
··· 1 - #!/bin/sh 2 - # SPDX-License-Identifier: GPL-2.0 3 - 4 - # amd-pstate-ut is a test module for testing the amd-pstate driver. 5 - # It can only run on x86 architectures and current cpufreq driver 6 - # must be amd-pstate. 7 - # (1) It can help all users to verify their processor support 8 - # (SBIOS/Firmware or Hardware). 9 - # (2) Kernel can have a basic function test to avoid the kernel 10 - # regression during the update. 11 - # (3) We can introduce more functional or performance tests to align 12 - # the result together, it will benefit power and performance scale optimization. 13 - 14 - # Kselftest framework requirement - SKIP code is 4. 15 - ksft_skip=4 16 - 17 - # amd-pstate-ut only run on x86/x86_64 AMD systems. 18 - ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/') 19 - VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}') 20 - 21 - if ! echo "$ARCH" | grep -q x86; then 22 - echo "$0 # Skipped: Test can only run on x86 architectures." 23 - exit $ksft_skip 24 - fi 25 - 26 - if ! echo "$VENDOR" | grep -iq amd; then 27 - echo "$0 # Skipped: Test can only run on AMD CPU." 28 - echo "$0 # Current cpu vendor is $VENDOR." 29 - exit $ksft_skip 30 - fi 31 - 32 - scaling_driver=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver) 33 - if [ "$scaling_driver" != "amd-pstate" ]; then 34 - echo "$0 # Skipped: Test can only run on amd-pstate driver." 35 - echo "$0 # Please set X86_AMD_PSTATE enabled." 36 - echo "$0 # Current cpufreq scaling drvier is $scaling_driver." 37 - exit $ksft_skip 38 - fi 39 - 40 - msg="Skip all tests:" 41 - if [ ! -w /dev ]; then 42 - echo $msg please run this as root >&2 43 - exit $ksft_skip 44 - fi 45 - 46 - if ! /sbin/modprobe -q -n amd-pstate-ut; then 47 - echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]" 48 - exit $ksft_skip 49 - fi 50 - if /sbin/modprobe -q amd-pstate-ut; then 51 - /sbin/modprobe -q -r amd-pstate-ut 52 - echo "amd-pstate-ut: ok" 53 - else 54 - echo "amd-pstate-ut: [FAIL]" 55 - exit 1 56 - fi
+38
tools/testing/selftests/amd-pstate/basic.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # amd-pstate-ut is a test module for testing the amd-pstate driver. 5 + # It can only run on x86 architectures and current cpufreq driver 6 + # must be amd-pstate. 7 + # (1) It can help all users to verify their processor support 8 + # (SBIOS/Firmware or Hardware). 9 + # (2) Kernel can have a basic function test to avoid the kernel 10 + # regression during the update. 11 + # (3) We can introduce more functional or performance tests to align 12 + # the result together, it will benefit power and performance scale optimization. 13 + 14 + # protect against multiple inclusion 15 + if [ $FILE_BASIC ]; then 16 + return 0 17 + else 18 + FILE_BASIC=DONE 19 + fi 20 + 21 + amd_pstate_basic() 22 + { 23 + printf "\n---------------------------------------------\n" 24 + printf "*** Running AMD P-state ut ***" 25 + printf "\n---------------------------------------------\n" 26 + 27 + if ! /sbin/modprobe -q -n amd-pstate-ut; then 28 + echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]" 29 + exit $ksft_skip 30 + fi 31 + if /sbin/modprobe -q amd-pstate-ut; then 32 + /sbin/modprobe -q -r amd-pstate-ut 33 + echo "amd-pstate-basic: ok" 34 + else 35 + echo "amd-pstate-basic: [FAIL]" 36 + exit 1 37 + fi 38 + }
+354
tools/testing/selftests/amd-pstate/gitsource.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # Testing and monitor the cpu desire performance, frequency, load, 5 + # power consumption and throughput etc. when this script trigger 6 + # gitsource test. 7 + # 1) Download and tar gitsource codes. 8 + # 2) Run gitsource benchmark on specific governors, ondemand or schedutil. 9 + # 3) Run tbench benchmark comparative test on acpi-cpufreq kernel driver. 10 + # 4) Get desire performance, frequency, load by perf. 11 + # 5) Get power consumption and throughput by amd_pstate_trace.py. 12 + # 6) Get run time by /usr/bin/time. 13 + # 7) Analyse test results and save it in file selftest.gitsource.csv. 14 + #8) Plot png images about time, energy and performance per watt for each test. 15 + 16 + # protect against multiple inclusion 17 + if [ $FILE_GITSOURCE ]; then 18 + return 0 19 + else 20 + FILE_GITSOURCE=DONE 21 + fi 22 + 23 + git_name="git-2.15.1" 24 + git_tar="$git_name.tar.gz" 25 + gitsource_url="https://github.com/git/git/archive/refs/tags/v2.15.1.tar.gz" 26 + gitsource_governors=("ondemand" "schedutil") 27 + 28 + # $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: time $7: energy, $8: PPW 29 + store_csv_gitsource() 30 + { 31 + echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1 32 + } 33 + 34 + # clear some special lines 35 + clear_csv_gitsource() 36 + { 37 + if [ -f $OUTFILE_GIT.csv ]; then 38 + sed -i '/Comprison(%)/d' $OUTFILE_GIT.csv 39 + sed -i "/$(scaling_name)/d" $OUTFILE_GIT.csv 40 + fi 41 + } 42 + 43 + # find string $1 in file csv and get the number of lines 44 + get_lines_csv_gitsource() 45 + { 46 + if [ -f $OUTFILE_GIT.csv ]; then 47 + return `grep -c "$1" $OUTFILE_GIT.csv` 48 + else 49 + return 0 50 + fi 51 + } 52 + 53 + pre_clear_gitsource() 54 + { 55 + post_clear_gitsource 56 + rm -rf gitsource_*.png 57 + clear_csv_gitsource 58 + } 59 + 60 + post_clear_gitsource() 61 + { 62 + rm -rf results/tracer-gitsource* 63 + rm -rf $OUTFILE_GIT*.log 64 + rm -rf $OUTFILE_GIT*.result 65 + } 66 + 67 + install_gitsource() 68 + { 69 + if [ ! -d $git_name ]; then 70 + printf "Download gitsource, please wait a moment ...\n\n" 71 + wget -O $git_tar $gitsource_url > /dev/null 2>&1 72 + 73 + printf "Tar gitsource ...\n\n" 74 + tar -xzf $git_tar 75 + fi 76 + } 77 + 78 + # $1: governor, $2: loop 79 + run_gitsource() 80 + { 81 + echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL" 82 + ./amd_pstate_trace.py -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 & 83 + 84 + printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n" 85 + cd $git_name 86 + perf stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o ../$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > ../$OUTFILE_GIT-perf-$1-$2.log 2>&1 87 + cd .. 88 + 89 + for job in `jobs -p` 90 + do 91 + echo "Waiting for job id $job" 92 + wait $job 93 + done 94 + } 95 + 96 + # $1: governor, $2: loop 97 + parse_gitsource() 98 + { 99 + awk '{print $5}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-des-perf-$1-$2.log 100 + avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-des-perf-$1-$2.log) 101 + printf "Gitsource-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result 102 + 103 + awk '{print $7}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-freq-$1-$2.log 104 + avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-freq-$1-$2.log) 105 + printf "Gitsource-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result 106 + 107 + awk '{print $11}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-load-$1-$2.log 108 + avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-load-$1-$2.log) 109 + printf "Gitsource-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result 110 + 111 + grep user $OUTFILE_GIT.time-gitsource-$1-$2.log | awk '{print $1}' | sed -e 's/user//' > $OUTFILE_GIT-time-$1-$2.log 112 + time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1-$2.log) 113 + printf "Gitsource-$1-#$2 user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result 114 + 115 + grep Joules $OUTFILE_GIT-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_GIT-energy-$1-$2.log 116 + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1-$2.log) 117 + printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result 118 + 119 + # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t 120 + # senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), 121 + # and t is time measured in seconds(s). This means that performance per watt becomes 122 + # 1/t 1/t 1 123 + # ----- = ----- = --- 124 + # P E/t E 125 + # with unit given by 1 per joule. 126 + ppw=`echo "scale=9;1/$en_sum" | bc | awk '{printf "%.9f", $0}'` 127 + printf "Gitsource-$1-#$2 performance per watt(1/J): $ppw\n" | tee -a $OUTFILE_GIT.result 128 + printf "\n" | tee -a $OUTFILE_GIT.result 129 + 130 + driver_name=`echo $(scaling_name)` 131 + store_csv_gitsource "$driver_name-$1" $2 $avg_des_perf $avg_freq $avg_load $time_sum $en_sum $ppw 132 + } 133 + 134 + # $1: governor 135 + loop_gitsource() 136 + { 137 + printf "\nGitsource total test times is $LOOP_TIMES for $1\n\n" 138 + for i in `seq 1 $LOOP_TIMES` 139 + do 140 + run_gitsource $1 $i 141 + parse_gitsource $1 $i 142 + done 143 + } 144 + 145 + # $1: governor 146 + gather_gitsource() 147 + { 148 + printf "Gitsource test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_GIT.result 149 + printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_GIT.result 150 + 151 + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_GIT-des-perf-$1.log 152 + avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-des-perf-$1.log) 153 + printf "Gitsource-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result 154 + 155 + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_GIT-freq-$1.log 156 + avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-freq-$1.log) 157 + printf "Gitsource-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result 158 + 159 + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_GIT-load-$1.log 160 + avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-load-$1.log) 161 + printf "Gitsource-$1 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result 162 + 163 + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "user time(s):" | awk '{print $NF}' > $OUTFILE_GIT-time-$1.log 164 + time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1.log) 165 + printf "Gitsource-$1 total user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result 166 + 167 + avg_time=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-time-$1.log) 168 + printf "Gitsource-$1 avg user times(s): $avg_time\n" | tee -a $OUTFILE_GIT.result 169 + 170 + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_GIT-energy-$1.log 171 + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1.log) 172 + printf "Gitsource-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result 173 + 174 + avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-energy-$1.log) 175 + printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result 176 + 177 + # Permance is the number of run gitsource per second, denoted 1/t, where 1 is the number of run gitsource in t 178 + # senconds. It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), 179 + # and t is time measured in seconds(s). This means that performance per watt becomes 180 + # 1/t 1/t 1 181 + # ----- = ----- = --- 182 + # P E/t E 183 + # with unit given by 1 per joule. 184 + ppw=`echo "scale=9;1/$avg_en" | bc | awk '{printf "%.9f", $0}'` 185 + printf "Gitsource-$1 performance per watt(1/J): $ppw\n" | tee -a $OUTFILE_GIT.result 186 + printf "\n" | tee -a $OUTFILE_GIT.result 187 + 188 + driver_name=`echo $(scaling_name)` 189 + store_csv_gitsource "$driver_name-$1" "Average" $avg_des_perf $avg_freq $avg_load $avg_time $avg_en $ppw 190 + } 191 + 192 + # $1: base scaling_driver $2: base governor $3: comparison scaling_driver $4: comparison governor 193 + __calc_comp_gitsource() 194 + { 195 + base=`grep "$1-$2" $OUTFILE_GIT.csv | grep "Average"` 196 + comp=`grep "$3-$4" $OUTFILE_GIT.csv | grep "Average"` 197 + 198 + if [ -n "$base" -a -n "$comp" ]; then 199 + printf "\n==================================================\n" | tee -a $OUTFILE_GIT.result 200 + printf "Gitsource comparison $1-$2 VS $3-$4" | tee -a $OUTFILE_GIT.result 201 + printf "\n==================================================\n" | tee -a $OUTFILE_GIT.result 202 + 203 + # get the base values 204 + des_perf_base=`echo "$base" | awk '{print $3}' | sed s/,//` 205 + freq_base=`echo "$base" | awk '{print $4}' | sed s/,//` 206 + load_base=`echo "$base" | awk '{print $5}' | sed s/,//` 207 + time_base=`echo "$base" | awk '{print $6}' | sed s/,//` 208 + energy_base=`echo "$base" | awk '{print $7}' | sed s/,//` 209 + ppw_base=`echo "$base" | awk '{print $8}' | sed s/,//` 210 + 211 + # get the comparison values 212 + des_perf_comp=`echo "$comp" | awk '{print $3}' | sed s/,//` 213 + freq_comp=`echo "$comp" | awk '{print $4}' | sed s/,//` 214 + load_comp=`echo "$comp" | awk '{print $5}' | sed s/,//` 215 + time_comp=`echo "$comp" | awk '{print $6}' | sed s/,//` 216 + energy_comp=`echo "$comp" | awk '{print $7}' | sed s/,//` 217 + ppw_comp=`echo "$comp" | awk '{print $8}' | sed s/,//` 218 + 219 + # compare the base and comp values 220 + des_perf_drop=`echo "scale=4;($des_perf_comp-$des_perf_base)*100/$des_perf_base" | bc | awk '{printf "%.4f", $0}'` 221 + printf "Gitsource-$1 des perf base: $des_perf_base comprison: $des_perf_comp percent: $des_perf_drop\n" | tee -a $OUTFILE_GIT.result 222 + 223 + freq_drop=`echo "scale=4;($freq_comp-$freq_base)*100/$freq_base" | bc | awk '{printf "%.4f", $0}'` 224 + printf "Gitsource-$1 freq base: $freq_base comprison: $freq_comp percent: $freq_drop\n" | tee -a $OUTFILE_GIT.result 225 + 226 + load_drop=`echo "scale=4;($load_comp-$load_base)*100/$load_base" | bc | awk '{printf "%.4f", $0}'` 227 + printf "Gitsource-$1 load base: $load_base comprison: $load_comp percent: $load_drop\n" | tee -a $OUTFILE_GIT.result 228 + 229 + time_drop=`echo "scale=4;($time_comp-$time_base)*100/$time_base" | bc | awk '{printf "%.4f", $0}'` 230 + printf "Gitsource-$1 time base: $time_base comprison: $time_comp percent: $time_drop\n" | tee -a $OUTFILE_GIT.result 231 + 232 + energy_drop=`echo "scale=4;($energy_comp-$energy_base)*100/$energy_base" | bc | awk '{printf "%.4f", $0}'` 233 + printf "Gitsource-$1 energy base: $energy_base comprison: $energy_comp percent: $energy_drop\n" | tee -a $OUTFILE_GIT.result 234 + 235 + ppw_drop=`echo "scale=4;($ppw_comp-$ppw_base)*100/$ppw_base" | bc | awk '{printf "%.4f", $0}'` 236 + printf "Gitsource-$1 performance per watt base: $ppw_base comprison: $ppw_comp percent: $ppw_drop\n" | tee -a $OUTFILE_GIT.result 237 + printf "\n" | tee -a $OUTFILE_GIT.result 238 + 239 + store_csv_gitsource "$1-$2 VS $3-$4" "Comprison(%)" "$des_perf_drop" "$freq_drop" "$load_drop" "$time_drop" "$energy_drop" "$ppw_drop" 240 + fi 241 + } 242 + 243 + # calculate the comparison(%) 244 + calc_comp_gitsource() 245 + { 246 + # acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil 247 + __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[0]} ${all_scaling_names[0]} ${gitsource_governors[1]} 248 + 249 + # amd-pstate-ondemand VS amd-pstate-schedutil 250 + __calc_comp_gitsource ${all_scaling_names[1]} ${gitsource_governors[0]} ${all_scaling_names[1]} ${gitsource_governors[1]} 251 + 252 + # acpi-cpufreq-ondemand VS amd-pstate-ondemand 253 + __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[0]} ${all_scaling_names[1]} ${gitsource_governors[0]} 254 + 255 + # acpi-cpufreq-schedutil VS amd-pstate-schedutil 256 + __calc_comp_gitsource ${all_scaling_names[0]} ${gitsource_governors[1]} ${all_scaling_names[1]} ${gitsource_governors[1]} 257 + } 258 + 259 + # $1: file_name, $2: title, $3: ylable, $4: column 260 + plot_png_gitsource() 261 + { 262 + # all_scaling_names[1] all_scaling_names[0] flag 263 + # amd-pstate acpi-cpufreq 264 + # N N 0 265 + # N Y 1 266 + # Y N 2 267 + # Y Y 3 268 + ret=`grep -c "${all_scaling_names[1]}" $OUTFILE_GIT.csv` 269 + if [ $ret -eq 0 ]; then 270 + ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_GIT.csv` 271 + if [ $ret -eq 0 ]; then 272 + flag=0 273 + else 274 + flag=1 275 + fi 276 + else 277 + ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_GIT.csv` 278 + if [ $ret -eq 0 ]; then 279 + flag=2 280 + else 281 + flag=3 282 + fi 283 + fi 284 + 285 + gnuplot << EOF 286 + set term png 287 + set output "$1" 288 + 289 + set title "$2" 290 + set xlabel "Test Cycles (round)" 291 + set ylabel "$3" 292 + 293 + set grid 294 + set style data histogram 295 + set style fill solid 0.5 border 296 + set boxwidth 0.8 297 + 298 + if ($flag == 1) { 299 + plot \ 300 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[0]}", \ 301 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[1]}" 302 + } else { 303 + if ($flag == 2) { 304 + plot \ 305 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[0]}", \ 306 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[1]}" 307 + } else { 308 + if ($flag == 3 ) { 309 + plot \ 310 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[0]}", \ 311 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${gitsource_governors[1]}", \ 312 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[0]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[0]}", \ 313 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${gitsource_governors[1]}/p' $OUTFILE_GIT.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${gitsource_governors[1]}" 314 + } 315 + } 316 + } 317 + quit 318 + EOF 319 + } 320 + 321 + amd_pstate_gitsource() 322 + { 323 + printf "\n---------------------------------------------\n" 324 + printf "*** Running gitsource ***" 325 + printf "\n---------------------------------------------\n" 326 + 327 + pre_clear_gitsource 328 + 329 + install_gitsource 330 + 331 + get_lines_csv_gitsource "Governor" 332 + if [ $? -eq 0 ]; then 333 + # add titles and unit for csv file 334 + store_csv_gitsource "Governor" "Round" "Des-perf" "Freq" "Load" "Time" "Energy" "Performance Per Watt" 335 + store_csv_gitsource "Unit" "" "" "GHz" "" "s" "J" "1/J" 336 + fi 337 + 338 + backup_governor 339 + for governor in ${gitsource_governors[*]} ; do 340 + printf "\nSpecified governor is $governor\n\n" 341 + switch_governor $governor 342 + loop_gitsource $governor 343 + gather_gitsource $governor 344 + done 345 + restore_governor 346 + 347 + plot_png_gitsource "gitsource_time.png" "Gitsource Benchmark Time" "Time (s)" 6 348 + plot_png_gitsource "gitsource_energy.png" "Gitsource Benchmark Energy" "Energy (J)" 7 349 + plot_png_gitsource "gitsource_ppw.png" "Gitsource Benchmark Performance Per Watt" "Performance Per Watt (1/J)" 8 350 + 351 + calc_comp_gitsource 352 + 353 + post_clear_gitsource 354 + }
+387
tools/testing/selftests/amd-pstate/run.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # protect against multiple inclusion 5 + if [ $FILE_MAIN ]; then 6 + return 0 7 + else 8 + FILE_MAIN=DONE 9 + fi 10 + 11 + source basic.sh 12 + source tbench.sh 13 + source gitsource.sh 14 + 15 + # amd-pstate-ut only run on x86/x86_64 AMD systems. 16 + ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/') 17 + VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}') 18 + 19 + msg="Skip all tests:" 20 + FUNC=all 21 + OUTFILE=selftest 22 + OUTFILE_TBENCH="$OUTFILE.tbench" 23 + OUTFILE_GIT="$OUTFILE.gitsource" 24 + 25 + SYSFS= 26 + CPUROOT= 27 + CPUFREQROOT= 28 + MAKE_CPUS= 29 + 30 + TIME_LIMIT=100 31 + PROCESS_NUM=128 32 + LOOP_TIMES=3 33 + TRACER_INTERVAL=10 34 + CURRENT_TEST=amd-pstate 35 + COMPARATIVE_TEST= 36 + 37 + # Kselftest framework requirement - SKIP code is 4. 38 + ksft_skip=4 39 + all_scaling_names=("acpi-cpufreq" "amd-pstate") 40 + 41 + # Get current cpufreq scaling driver name 42 + scaling_name() 43 + { 44 + if [ "$COMPARATIVE_TEST" = "" ]; then 45 + echo "$CURRENT_TEST" 46 + else 47 + echo "$COMPARATIVE_TEST" 48 + fi 49 + } 50 + 51 + # Counts CPUs with cpufreq directories 52 + count_cpus() 53 + { 54 + count=0; 55 + 56 + for cpu in `ls $CPUROOT | grep "cpu[0-9].*"`; do 57 + if [ -d $CPUROOT/$cpu/cpufreq ]; then 58 + let count=count+1; 59 + fi 60 + done 61 + 62 + echo $count; 63 + } 64 + 65 + # $1: policy 66 + find_current_governor() 67 + { 68 + cat $CPUFREQROOT/$1/scaling_governor 69 + } 70 + 71 + backup_governor() 72 + { 73 + policies=$(ls $CPUFREQROOT| grep "policy[0-9].*") 74 + for policy in $policies; do 75 + cur_gov=$(find_current_governor $policy) 76 + echo "$policy $cur_gov" >> $OUTFILE.backup_governor.log 77 + done 78 + 79 + printf "Governor $cur_gov backup done.\n" 80 + } 81 + 82 + restore_governor() 83 + { 84 + i=0; 85 + 86 + policies=$(awk '{print $1}' $OUTFILE.backup_governor.log) 87 + for policy in $policies; do 88 + let i++; 89 + governor=$(sed -n ''$i'p' $OUTFILE.backup_governor.log | awk '{print $2}') 90 + 91 + # switch governor 92 + echo $governor > $CPUFREQROOT/$policy/scaling_governor 93 + done 94 + 95 + printf "Governor restored to $governor.\n" 96 + } 97 + 98 + # $1: governor 99 + switch_governor() 100 + { 101 + policies=$(ls $CPUFREQROOT| grep "policy[0-9].*") 102 + for policy in $policies; do 103 + filepath=$CPUFREQROOT/$policy/scaling_available_governors 104 + 105 + # Exit if cpu isn't managed by cpufreq core 106 + if [ ! -f $filepath ]; then 107 + return; 108 + fi 109 + 110 + echo $1 > $CPUFREQROOT/$policy/scaling_governor 111 + done 112 + 113 + printf "Switched governor to $1.\n" 114 + } 115 + 116 + # All amd-pstate tests 117 + amd_pstate_all() 118 + { 119 + printf "\n=============================================\n" 120 + printf "***** Running AMD P-state Sanity Tests *****\n" 121 + printf "=============================================\n\n" 122 + 123 + count=$(count_cpus) 124 + if [ $count = 0 ]; then 125 + printf "No cpu is managed by cpufreq core, exiting\n" 126 + exit; 127 + else 128 + printf "AMD P-state manages: $count CPUs\n" 129 + fi 130 + 131 + # unit test for amd-pstate kernel driver 132 + amd_pstate_basic 133 + 134 + # tbench 135 + amd_pstate_tbench 136 + 137 + # gitsource 138 + amd_pstate_gitsource 139 + } 140 + 141 + help() 142 + { 143 + printf "Usage: $0 [OPTION...] 144 + [-h <help>] 145 + [-o <output-file-for-dump>] 146 + [-c <all: All testing, 147 + basic: Basic testing, 148 + tbench: Tbench testing, 149 + gitsource: Gitsource testing.>] 150 + [-t <tbench time limit>] 151 + [-p <tbench process number>] 152 + [-l <loop times for tbench>] 153 + [-i <amd tracer interval>] 154 + [-m <comparative test: acpi-cpufreq>] 155 + \n" 156 + exit 2 157 + } 158 + 159 + parse_arguments() 160 + { 161 + while getopts ho:c:t:p:l:i:m: arg 162 + do 163 + case $arg in 164 + h) # --help 165 + help 166 + ;; 167 + 168 + c) # --func_type (Function to perform: basic, tbench, gitsource (default: all)) 169 + FUNC=$OPTARG 170 + ;; 171 + 172 + o) # --output-file (Output file to store dumps) 173 + OUTFILE=$OPTARG 174 + ;; 175 + 176 + t) # --tbench-time-limit 177 + TIME_LIMIT=$OPTARG 178 + ;; 179 + 180 + p) # --tbench-process-number 181 + PROCESS_NUM=$OPTARG 182 + ;; 183 + 184 + l) # --tbench/gitsource-loop-times 185 + LOOP_TIMES=$OPTARG 186 + ;; 187 + 188 + i) # --amd-tracer-interval 189 + TRACER_INTERVAL=$OPTARG 190 + ;; 191 + 192 + m) # --comparative-test 193 + COMPARATIVE_TEST=$OPTARG 194 + ;; 195 + 196 + *) 197 + help 198 + ;; 199 + esac 200 + done 201 + } 202 + 203 + command_perf() 204 + { 205 + if ! command -v perf > /dev/null; then 206 + echo $msg please install perf. >&2 207 + exit $ksft_skip 208 + fi 209 + } 210 + 211 + command_tbench() 212 + { 213 + if ! command -v tbench > /dev/null; then 214 + if apt policy dbench > /dev/null 2>&1; then 215 + echo $msg apt install dbench >&2 216 + exit $ksft_skip 217 + elif yum list available | grep dbench > /dev/null 2>&1; then 218 + echo $msg yum install dbench >&2 219 + exit $ksft_skip 220 + fi 221 + fi 222 + 223 + if ! command -v tbench > /dev/null; then 224 + echo $msg please install tbench. >&2 225 + exit $ksft_skip 226 + fi 227 + } 228 + 229 + prerequisite() 230 + { 231 + if ! echo "$ARCH" | grep -q x86; then 232 + echo "$0 # Skipped: Test can only run on x86 architectures." 233 + exit $ksft_skip 234 + fi 235 + 236 + if ! echo "$VENDOR" | grep -iq amd; then 237 + echo "$0 # Skipped: Test can only run on AMD CPU." 238 + echo "$0 # Current cpu vendor is $VENDOR." 239 + exit $ksft_skip 240 + fi 241 + 242 + scaling_driver=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver) 243 + if [ "$COMPARATIVE_TEST" = "" ]; then 244 + if [ "$scaling_driver" != "$CURRENT_TEST" ]; then 245 + echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test." 246 + echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test." 247 + echo "$0 # Current cpufreq scaling drvier is $scaling_driver." 248 + exit $ksft_skip 249 + fi 250 + else 251 + case "$FUNC" in 252 + "tbench" | "gitsource") 253 + if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then 254 + echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver." 255 + echo "$0 # Current cpufreq scaling drvier is $scaling_driver." 256 + exit $ksft_skip 257 + fi 258 + ;; 259 + 260 + *) 261 + echo "$0 # Skipped: Comparison test are only for tbench or gitsource." 262 + echo "$0 # Current comparative test is for $FUNC." 263 + exit $ksft_skip 264 + ;; 265 + esac 266 + fi 267 + 268 + if [ ! -w /dev ]; then 269 + echo $msg please run this as root >&2 270 + exit $ksft_skip 271 + fi 272 + 273 + case "$FUNC" in 274 + "all") 275 + command_perf 276 + command_tbench 277 + ;; 278 + 279 + "tbench") 280 + command_perf 281 + command_tbench 282 + ;; 283 + 284 + "gitsource") 285 + command_perf 286 + ;; 287 + esac 288 + 289 + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 290 + 291 + if [ ! -d "$SYSFS" ]; then 292 + echo $msg sysfs is not mounted >&2 293 + exit 2 294 + fi 295 + 296 + CPUROOT=$SYSFS/devices/system/cpu 297 + CPUFREQROOT="$CPUROOT/cpufreq" 298 + 299 + if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then 300 + echo $msg cpus not available in sysfs >&2 301 + exit 2 302 + fi 303 + 304 + if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then 305 + echo $msg cpufreq directory not available in sysfs >&2 306 + exit 2 307 + fi 308 + } 309 + 310 + do_test() 311 + { 312 + # Check if CPUs are managed by cpufreq or not 313 + count=$(count_cpus) 314 + MAKE_CPUS=$((count*2)) 315 + 316 + if [ $count = 0 ]; then 317 + echo "No cpu is managed by cpufreq core, exiting" 318 + exit 2; 319 + fi 320 + 321 + case "$FUNC" in 322 + "all") 323 + amd_pstate_all 324 + ;; 325 + 326 + "basic") 327 + amd_pstate_basic 328 + ;; 329 + 330 + "tbench") 331 + amd_pstate_tbench 332 + ;; 333 + 334 + "gitsource") 335 + amd_pstate_gitsource 336 + ;; 337 + 338 + *) 339 + echo "Invalid [-f] function type" 340 + help 341 + ;; 342 + esac 343 + } 344 + 345 + # clear dumps 346 + pre_clear_dumps() 347 + { 348 + case "$FUNC" in 349 + "all") 350 + rm -rf $OUTFILE.log 351 + rm -rf $OUTFILE.backup_governor.log 352 + rm -rf *.png 353 + ;; 354 + 355 + "tbench") 356 + rm -rf $OUTFILE.log 357 + rm -rf $OUTFILE.backup_governor.log 358 + rm -rf tbench_*.png 359 + ;; 360 + 361 + "gitsource") 362 + rm -rf $OUTFILE.log 363 + rm -rf $OUTFILE.backup_governor.log 364 + rm -rf gitsource_*.png 365 + ;; 366 + 367 + *) 368 + ;; 369 + esac 370 + } 371 + 372 + post_clear_dumps() 373 + { 374 + rm -rf $OUTFILE.log 375 + rm -rf $OUTFILE.backup_governor.log 376 + } 377 + 378 + # Parse arguments 379 + parse_arguments $@ 380 + 381 + # Make sure all requirements are met 382 + prerequisite 383 + 384 + # Run requested functions 385 + pre_clear_dumps 386 + do_test | tee -a $OUTFILE.log 387 + post_clear_dumps
+339
tools/testing/selftests/amd-pstate/tbench.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # Testing and monitor the cpu desire performance, frequency, load, 5 + # power consumption and throughput etc.when this script trigger tbench 6 + # test cases. 7 + # 1) Run tbench benchmark on specific governors, ondemand or schedutil. 8 + # 2) Run tbench benchmark comparative test on acpi-cpufreq kernel driver. 9 + # 3) Get desire performance, frequency, load by perf. 10 + # 4) Get power consumption and throughput by amd_pstate_trace.py. 11 + # 5) Analyse test results and save it in file selftest.tbench.csv. 12 + # 6) Plot png images about performance, energy and performance per watt for each test. 13 + 14 + # protect against multiple inclusion 15 + if [ $FILE_TBENCH ]; then 16 + return 0 17 + else 18 + FILE_TBENCH=DONE 19 + fi 20 + 21 + tbench_governors=("ondemand" "schedutil") 22 + 23 + # $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: performance, $7: energy, $8: performance per watt 24 + store_csv_tbench() 25 + { 26 + echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1 27 + } 28 + 29 + # clear some special lines 30 + clear_csv_tbench() 31 + { 32 + if [ -f $OUTFILE_TBENCH.csv ]; then 33 + sed -i '/Comprison(%)/d' $OUTFILE_TBENCH.csv 34 + sed -i "/$(scaling_name)/d" $OUTFILE_TBENCH.csv 35 + fi 36 + } 37 + 38 + # find string $1 in file csv and get the number of lines 39 + get_lines_csv_tbench() 40 + { 41 + if [ -f $OUTFILE_TBENCH.csv ]; then 42 + return `grep -c "$1" $OUTFILE_TBENCH.csv` 43 + else 44 + return 0 45 + fi 46 + } 47 + 48 + pre_clear_tbench() 49 + { 50 + post_clear_tbench 51 + rm -rf tbench_*.png 52 + clear_csv_tbench 53 + } 54 + 55 + post_clear_tbench() 56 + { 57 + rm -rf results/tracer-tbench* 58 + rm -rf $OUTFILE_TBENCH*.log 59 + rm -rf $OUTFILE_TBENCH*.result 60 + 61 + } 62 + 63 + # $1: governor, $2: loop 64 + run_tbench() 65 + { 66 + echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL" 67 + ./amd_pstate_trace.py -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 & 68 + 69 + printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n" 70 + tbench_srv > /dev/null 2>&1 & 71 + perf stat -a --per-socket -I 1000 -e power/energy-pkg/ tbench -t $TIME_LIMIT $PROCESS_NUM > $OUTFILE_TBENCH-perf-$1-$2.log 2>&1 72 + 73 + pid=`pidof tbench_srv` 74 + kill $pid 75 + 76 + for job in `jobs -p` 77 + do 78 + echo "Waiting for job id $job" 79 + wait $job 80 + done 81 + } 82 + 83 + # $1: governor, $2: loop 84 + parse_tbench() 85 + { 86 + awk '{print $5}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-des-perf-$1-$2.log 87 + avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-des-perf-$1-$2.log) 88 + printf "Tbench-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result 89 + 90 + awk '{print $7}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-freq-$1-$2.log 91 + avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-freq-$1-$2.log) 92 + printf "Tbench-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result 93 + 94 + awk '{print $11}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-load-$1-$2.log 95 + avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-load-$1-$2.log) 96 + printf "Tbench-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result 97 + 98 + grep Throughput $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $2}' > $OUTFILE_TBENCH-throughput-$1-$2.log 99 + tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1-$2.log) 100 + printf "Tbench-$1-#$2 throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result 101 + 102 + grep Joules $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_TBENCH-energy-$1-$2.log 103 + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1-$2.log) 104 + printf "Tbench-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result 105 + 106 + # Permance is throughput per second, denoted T/t, where T is throught rendered in t seconds. 107 + # It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), 108 + # and t is time measured in seconds(s). This means that performance per watt becomes 109 + # T/t T/t T 110 + # --- = --- = --- 111 + # P E/t E 112 + # with unit given by MB per joule. 113 + ppw=`echo "scale=4;($TIME_LIMIT-1)*$tp_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'` 114 + printf "Tbench-$1-#$2 performance per watt(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result 115 + printf "\n" | tee -a $OUTFILE_TBENCH.result 116 + 117 + driver_name=`echo $(scaling_name)` 118 + store_csv_tbench "$driver_name-$1" $2 $avg_des_perf $avg_freq $avg_load $tp_sum $en_sum $ppw 119 + } 120 + 121 + # $1: governor 122 + loop_tbench() 123 + { 124 + printf "\nTbench total test times is $LOOP_TIMES for $1\n\n" 125 + for i in `seq 1 $LOOP_TIMES` 126 + do 127 + run_tbench $1 $i 128 + parse_tbench $1 $i 129 + done 130 + } 131 + 132 + # $1: governor 133 + gather_tbench() 134 + { 135 + printf "Tbench test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_TBENCH.result 136 + printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_TBENCH.result 137 + 138 + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_TBENCH-des-perf-$1.log 139 + avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-des-perf-$1.log) 140 + printf "Tbench-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result 141 + 142 + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_TBENCH-freq-$1.log 143 + avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-freq-$1.log) 144 + printf "Tbench-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result 145 + 146 + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_TBENCH-load-$1.log 147 + avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-load-$1.log) 148 + printf "Tbench-$1 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result 149 + 150 + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "throughput(MB/s):" | awk '{print $NF}' > $OUTFILE_TBENCH-throughput-$1.log 151 + tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1.log) 152 + printf "Tbench-$1 total throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result 153 + 154 + avg_tp=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-throughput-$1.log) 155 + printf "Tbench-$1 avg throughput(MB/s): $avg_tp\n" | tee -a $OUTFILE_TBENCH.result 156 + 157 + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_TBENCH-energy-$1.log 158 + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1.log) 159 + printf "Tbench-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result 160 + 161 + avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-energy-$1.log) 162 + printf "Tbench-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_TBENCH.result 163 + 164 + # Permance is throughput per second, denoted T/t, where T is throught rendered in t seconds. 165 + # It is well known that P=E/t, where P is power measured in watts(W), E is energy measured in joules(J), 166 + # and t is time measured in seconds(s). This means that performance per watt becomes 167 + # T/t T/t T 168 + # --- = --- = --- 169 + # P E/t E 170 + # with unit given by MB per joule. 171 + ppw=`echo "scale=4;($TIME_LIMIT-1)*$avg_tp/$avg_en" | bc | awk '{printf "%.4f", $0}'` 172 + printf "Tbench-$1 performance per watt(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result 173 + printf "\n" | tee -a $OUTFILE_TBENCH.result 174 + 175 + driver_name=`echo $(scaling_name)` 176 + store_csv_tbench "$driver_name-$1" "Average" $avg_des_perf $avg_freq $avg_load $avg_tp $avg_en $ppw 177 + } 178 + 179 + # $1: base scaling_driver $2: base governor $3: comparative scaling_driver $4: comparative governor 180 + __calc_comp_tbench() 181 + { 182 + base=`grep "$1-$2" $OUTFILE_TBENCH.csv | grep "Average"` 183 + comp=`grep "$3-$4" $OUTFILE_TBENCH.csv | grep "Average"` 184 + 185 + if [ -n "$base" -a -n "$comp" ]; then 186 + printf "\n==================================================\n" | tee -a $OUTFILE_TBENCH.result 187 + printf "Tbench comparison $1-$2 VS $3-$4" | tee -a $OUTFILE_TBENCH.result 188 + printf "\n==================================================\n" | tee -a $OUTFILE_TBENCH.result 189 + 190 + # get the base values 191 + des_perf_base=`echo "$base" | awk '{print $3}' | sed s/,//` 192 + freq_base=`echo "$base" | awk '{print $4}' | sed s/,//` 193 + load_base=`echo "$base" | awk '{print $5}' | sed s/,//` 194 + perf_base=`echo "$base" | awk '{print $6}' | sed s/,//` 195 + energy_base=`echo "$base" | awk '{print $7}' | sed s/,//` 196 + ppw_base=`echo "$base" | awk '{print $8}' | sed s/,//` 197 + 198 + # get the comparative values 199 + des_perf_comp=`echo "$comp" | awk '{print $3}' | sed s/,//` 200 + freq_comp=`echo "$comp" | awk '{print $4}' | sed s/,//` 201 + load_comp=`echo "$comp" | awk '{print $5}' | sed s/,//` 202 + perf_comp=`echo "$comp" | awk '{print $6}' | sed s/,//` 203 + energy_comp=`echo "$comp" | awk '{print $7}' | sed s/,//` 204 + ppw_comp=`echo "$comp" | awk '{print $8}' | sed s/,//` 205 + 206 + # compare the base and comp values 207 + des_perf_drop=`echo "scale=4;($des_perf_comp-$des_perf_base)*100/$des_perf_base" | bc | awk '{printf "%.4f", $0}'` 208 + printf "Tbench-$1 des perf base: $des_perf_base comprison: $des_perf_comp percent: $des_perf_drop\n" | tee -a $OUTFILE_TBENCH.result 209 + 210 + freq_drop=`echo "scale=4;($freq_comp-$freq_base)*100/$freq_base" | bc | awk '{printf "%.4f", $0}'` 211 + printf "Tbench-$1 freq base: $freq_base comprison: $freq_comp percent: $freq_drop\n" | tee -a $OUTFILE_TBENCH.result 212 + 213 + load_drop=`echo "scale=4;($load_comp-$load_base)*100/$load_base" | bc | awk '{printf "%.4f", $0}'` 214 + printf "Tbench-$1 load base: $load_base comprison: $load_comp percent: $load_drop\n" | tee -a $OUTFILE_TBENCH.result 215 + 216 + perf_drop=`echo "scale=4;($perf_comp-$perf_base)*100/$perf_base" | bc | awk '{printf "%.4f", $0}'` 217 + printf "Tbench-$1 perf base: $perf_base comprison: $perf_comp percent: $perf_drop\n" | tee -a $OUTFILE_TBENCH.result 218 + 219 + energy_drop=`echo "scale=4;($energy_comp-$energy_base)*100/$energy_base" | bc | awk '{printf "%.4f", $0}'` 220 + printf "Tbench-$1 energy base: $energy_base comprison: $energy_comp percent: $energy_drop\n" | tee -a $OUTFILE_TBENCH.result 221 + 222 + ppw_drop=`echo "scale=4;($ppw_comp-$ppw_base)*100/$ppw_base" | bc | awk '{printf "%.4f", $0}'` 223 + printf "Tbench-$1 performance per watt base: $ppw_base comprison: $ppw_comp percent: $ppw_drop\n" | tee -a $OUTFILE_TBENCH.result 224 + printf "\n" | tee -a $OUTFILE_TBENCH.result 225 + 226 + store_csv_tbench "$1-$2 VS $3-$4" "Comprison(%)" "$des_perf_drop" "$freq_drop" "$load_drop" "$perf_drop" "$energy_drop" "$ppw_drop" 227 + fi 228 + } 229 + 230 + # calculate the comparison(%) 231 + calc_comp_tbench() 232 + { 233 + # acpi-cpufreq-ondemand VS acpi-cpufreq-schedutil 234 + __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[0]} ${all_scaling_names[0]} ${tbench_governors[1]} 235 + 236 + # amd-pstate-ondemand VS amd-pstate-schedutil 237 + __calc_comp_tbench ${all_scaling_names[1]} ${tbench_governors[0]} ${all_scaling_names[1]} ${tbench_governors[1]} 238 + 239 + # acpi-cpufreq-ondemand VS amd-pstate-ondemand 240 + __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[0]} ${all_scaling_names[1]} ${tbench_governors[0]} 241 + 242 + # acpi-cpufreq-schedutil VS amd-pstate-schedutil 243 + __calc_comp_tbench ${all_scaling_names[0]} ${tbench_governors[1]} ${all_scaling_names[1]} ${tbench_governors[1]} 244 + } 245 + 246 + # $1: file_name, $2: title, $3: ylable, $4: column 247 + plot_png_tbench() 248 + { 249 + # all_scaling_names[1] all_scaling_names[0] flag 250 + # amd-pstate acpi-cpufreq 251 + # N N 0 252 + # N Y 1 253 + # Y N 2 254 + # Y Y 3 255 + ret=`grep -c "${all_scaling_names[1]}" $OUTFILE_TBENCH.csv` 256 + if [ $ret -eq 0 ]; then 257 + ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_TBENCH.csv` 258 + if [ $ret -eq 0 ]; then 259 + flag=0 260 + else 261 + flag=1 262 + fi 263 + else 264 + ret=`grep -c "${all_scaling_names[0]}" $OUTFILE_TBENCH.csv` 265 + if [ $ret -eq 0 ]; then 266 + flag=2 267 + else 268 + flag=3 269 + fi 270 + fi 271 + 272 + gnuplot << EOF 273 + set term png 274 + set output "$1" 275 + 276 + set title "$2" 277 + set xlabel "Test Cycles (round)" 278 + set ylabel "$3" 279 + 280 + set grid 281 + set style data histogram 282 + set style fill solid 0.5 border 283 + set boxwidth 0.8 284 + 285 + if ($flag == 1) { 286 + plot \ 287 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[0]}", \ 288 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[1]}" 289 + } else { 290 + if ($flag == 2) { 291 + plot \ 292 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[0]}", \ 293 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[1]}" 294 + } else { 295 + if ($flag == 3 ) { 296 + plot \ 297 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[0]}", \ 298 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[0]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[0]}-${tbench_governors[1]}", \ 299 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[0]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[0]}", \ 300 + "<(sed -n -e 's/,//g' -e '/${all_scaling_names[1]}-${tbench_governors[1]}/p' $OUTFILE_TBENCH.csv)" using $4:xtic(2) title "${all_scaling_names[1]}-${tbench_governors[1]}" 301 + } 302 + } 303 + } 304 + quit 305 + EOF 306 + } 307 + 308 + amd_pstate_tbench() 309 + { 310 + printf "\n---------------------------------------------\n" 311 + printf "*** Running tbench ***" 312 + printf "\n---------------------------------------------\n" 313 + 314 + pre_clear_tbench 315 + 316 + get_lines_csv_tbench "Governor" 317 + if [ $? -eq 0 ]; then 318 + # add titles and unit for csv file 319 + store_csv_tbench "Governor" "Round" "Des-perf" "Freq" "Load" "Performance" "Energy" "Performance Per Watt" 320 + store_csv_tbench "Unit" "" "" "GHz" "" "MB/s" "J" "MB/J" 321 + fi 322 + 323 + backup_governor 324 + for governor in ${tbench_governors[*]} ; do 325 + printf "\nSpecified governor is $governor\n\n" 326 + switch_governor $governor 327 + loop_tbench $governor 328 + gather_tbench $governor 329 + done 330 + restore_governor 331 + 332 + plot_png_tbench "tbench_perfromance.png" "Tbench Benchmark Performance" "Performance" 6 333 + plot_png_tbench "tbench_energy.png" "Tbench Benchmark Energy" "Energy (J)" 7 334 + plot_png_tbench "tbench_ppw.png" "Tbench Benchmark Performance Per Watt" "Performance Per Watt (MB/J)" 8 335 + 336 + calc_comp_tbench 337 + 338 + post_clear_tbench 339 + }
+5
tools/testing/selftests/efivarfs/efivarfs.sh
··· 87 87 { 88 88 local file=$efivarfs_mount/$FUNCNAME-$test_guid 89 89 ./create-read $file 90 + if [ $? -ne 0 ]; then 91 + echo "create and read $file failed" 92 + file_cleanup $file 93 + exit 1 94 + fi 90 95 file_cleanup $file 91 96 } 92 97
+11 -4
tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
··· 38 38 39 39 test_event_enabled() { 40 40 val=$1 41 + check_times=10 # wait for 10 * SLEEP_TIME at most 41 42 42 - e=`cat $EVENT_ENABLE` 43 - if [ "$e" != $val ]; then 44 - fail "Expected $val but found $e" 45 - fi 43 + while [ $check_times -ne 0 ]; do 44 + e=`cat $EVENT_ENABLE` 45 + if [ "$e" == $val ]; then 46 + return 0 47 + fi 48 + sleep $SLEEP_TIME 49 + check_times=$((check_times - 1)) 50 + done 51 + 52 + fail "Expected $val but found $e" 46 53 } 47 54 48 55 run_enable_disable() {
+7 -1
tools/testing/selftests/ftrace/test.d/functions
··· 142 142 143 143 check_requires() { # Check required files and tracers 144 144 for i in "$@" ; do 145 + p=${i%:program} 145 146 r=${i%:README} 146 147 t=${i%:tracer} 147 - if [ $t != $i ]; then 148 + if [ $p != $i ]; then 149 + if ! which $p ; then 150 + echo "Required program $p is not found." 151 + exit_unresolved 152 + fi 153 + elif [ $t != $i ]; then 148 154 if ! grep -wq $t available_tracers ; then 149 155 echo "Required tracer $t is not configured." 150 156 exit_unsupported
+4 -4
tools/testing/selftests/ftrace/test.d/preemptirq/irqsoff_tracer.tc
··· 46 46 grep -q "tracer: preemptoff" trace || fail 47 47 48 48 # Check the end of the section 49 - egrep -q "5.....us : <stack trace>" trace || fail 49 + grep -E -q "5.....us : <stack trace>" trace || fail 50 50 51 51 # Check for 500ms of latency 52 - egrep -q "latency: 5..... us" trace || fail 52 + grep -E -q "latency: 5..... us" trace || fail 53 53 54 54 reset_tracer 55 55 ··· 69 69 grep -q "tracer: irqsoff" trace || fail 70 70 71 71 # Check the end of the section 72 - egrep -q "5.....us : <stack trace>" trace || fail 72 + grep -E -q "5.....us : <stack trace>" trace || fail 73 73 74 74 # Check for 500ms of latency 75 - egrep -q "latency: 5..... us" trace || fail 75 + grep -E -q "latency: 5..... us" trace || fail 76 76 77 77 reset_tracer 78 78 exit 0
+1 -6
tools/testing/selftests/ftrace/test.d/tracer/wakeup.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: Test wakeup tracer 4 - # requires: wakeup:tracer 5 - 6 - if ! which chrt ; then 7 - echo "chrt is not found. This test requires nice command." 8 - exit_unresolved 9 - fi 4 + # requires: wakeup:tracer chrt:program 10 5 11 6 echo wakeup > current_tracer 12 7 echo 1 > tracing_on
+1 -6
tools/testing/selftests/ftrace/test.d/tracer/wakeup_rt.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: Test wakeup RT tracer 4 - # requires: wakeup_rt:tracer 5 - 6 - if ! which chrt ; then 7 - echo "chrt is not found. This test requires chrt command." 8 - exit_unresolved 9 - fi 4 + # requires: wakeup_rt:tracer chrt:program 10 5 11 6 echo wakeup_rt > current_tracer 12 7 echo 1 > tracing_on
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test field variable support 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event combined histogram trigger 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger onchange action 4 - # requires: set_event "onchange(var)":README 4 + # requires: set_event "onchange(var)":README ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger onmatch action 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger onmatch-onmax action 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger onmax action 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger snapshot action 4 - # requires: set_event snapshot events/sched/sched_process_fork/hist "onchange(var)":README "snapshot()":README 4 + # requires: set_event snapshot events/sched/sched_process_fork/hist "onchange(var)":README "snapshot()":README ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
··· 14 14 SYNTH="synth_open" 15 15 EPROBE="eprobe_open" 16 16 17 - echo "$SYNTH u64 filename; s64 ret;" > synthetic_events 17 + echo "$SYNTH unsigned long filename; long ret;" > synthetic_events 18 18 echo "hist:keys=common_pid:__arg__1=$FIELD" > events/$SYSTEM/$START/trigger 19 19 echo "hist:keys=common_pid:filename=\$__arg__1,ret=ret:onmatch($SYSTEM.$START).trace($SYNTH,\$filename,\$ret)" > events/$SYSTEM/$END/trigger 20 20
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-dynstring.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger trace action with dynamic string param 4 - # requires: set_event synthetic_events events/sched/sched_process_exec/hist "char name[]' >> synthetic_events":README 4 + # requires: set_event synthetic_events events/sched/sched_process_exec/hist "char name[]' >> synthetic_events":README ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-trace-action-hist.tc
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # description: event trigger - test inter-event histogram trigger trace action 4 - # requires: set_event synthetic_events events/sched/sched_process_fork/hist "trace(<synthetic_event>":README 4 + # requires: set_event synthetic_events events/sched/sched_process_fork/hist "trace(<synthetic_event>":README ping:program 5 5 6 6 fail() { #msg 7 7 echo $1
+1 -1
tools/testing/selftests/gpio/gpio-sim.sh
··· 27 27 continue 28 28 fi 29 29 30 - LINES=`ls $CONFIGFS_DIR/$CHIP/$BANK/ | egrep ^line` 30 + LINES=`ls $CONFIGFS_DIR/$CHIP/$BANK/ | grep -E ^line` 31 31 if [ "$?" = 0 ]; then 32 32 for LINE in $LINES; do 33 33 if [ -e $CONFIGFS_DIR/$CHIP/$BANK/$LINE/hog ]; then
+1 -1
tools/testing/selftests/kselftest_deps.sh
··· 90 90 pass_cnt=0 91 91 92 92 # Get all TARGETS from selftests Makefile 93 - targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) 93 + targets=$(grep -E "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) 94 94 95 95 # Single test case 96 96 if [ $# -eq 2 ]
+5
tools/testing/selftests/lib.mk
··· 123 123 clean: 124 124 $(CLEAN) 125 125 126 + # Enables to extend CFLAGS and LDFLAGS from command line, e.g. 127 + # make USERCFLAGS=-Werror USERLDFLAGS=-static 128 + CFLAGS += $(USERCFLAGS) 129 + LDFLAGS += $(USERLDFLAGS) 130 + 126 131 # When make O= with kselftest target from main level 127 132 # the following aren't defined. 128 133 #
+32 -1
tools/testing/selftests/rtc/rtctest.c
··· 31 31 32 32 FIXTURE_SETUP(rtc) { 33 33 self->fd = open(rtc_file, O_RDONLY); 34 - ASSERT_NE(-1, self->fd); 35 34 } 36 35 37 36 FIXTURE_TEARDOWN(rtc) { ··· 40 41 TEST_F(rtc, date_read) { 41 42 int rc; 42 43 struct rtc_time rtc_tm; 44 + 45 + if (self->fd == -1 && errno == ENOENT) 46 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 47 + ASSERT_NE(-1, self->fd); 43 48 44 49 /* Read the RTC time/date */ 45 50 rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); ··· 88 85 struct rtc_time rtc_tm; 89 86 time_t start_rtc_read, prev_rtc_read; 90 87 88 + if (self->fd == -1 && errno == ENOENT) 89 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 90 + ASSERT_NE(-1, self->fd); 91 + 91 92 TH_LOG("Continuously reading RTC time for %ds (with %dms breaks after every read).", 92 93 READ_LOOP_DURATION_SEC, READ_LOOP_SLEEP_MS); 93 94 ··· 126 119 int i, rc, irq = 0; 127 120 unsigned long data; 128 121 122 + if (self->fd == -1 && errno == ENOENT) 123 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 124 + ASSERT_NE(-1, self->fd); 125 + 129 126 /* Turn on update interrupts */ 130 127 rc = ioctl(self->fd, RTC_UIE_ON, 0); 131 128 if (rc == -1) { ··· 154 143 TEST_F(rtc, uie_select) { 155 144 int i, rc, irq = 0; 156 145 unsigned long data; 146 + 147 + if (self->fd == -1 && errno == ENOENT) 148 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 149 + ASSERT_NE(-1, self->fd); 157 150 158 151 /* Turn on update interrupts */ 159 152 rc = ioctl(self->fd, RTC_UIE_ON, 0); ··· 197 182 fd_set readfds; 198 183 time_t secs, new; 199 184 int rc; 185 + 186 + if (self->fd == -1 && errno == ENOENT) 187 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 188 + ASSERT_NE(-1, self->fd); 200 189 201 190 rc = ioctl(self->fd, RTC_RD_TIME, &tm); 202 191 ASSERT_NE(-1, rc); ··· 256 237 time_t secs, new; 257 238 int rc; 258 239 240 + if (self->fd == -1 && errno == ENOENT) 241 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 242 + ASSERT_NE(-1, self->fd); 243 + 259 244 rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time); 260 245 ASSERT_NE(-1, rc); 261 246 ··· 307 284 fd_set readfds; 308 285 time_t secs, new; 309 286 int rc; 287 + 288 + if (self->fd == -1 && errno == ENOENT) 289 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 290 + ASSERT_NE(-1, self->fd); 310 291 311 292 rc = ioctl(self->fd, RTC_RD_TIME, &tm); 312 293 ASSERT_NE(-1, rc); ··· 365 338 fd_set readfds; 366 339 time_t secs, new; 367 340 int rc; 341 + 342 + if (self->fd == -1 && errno == ENOENT) 343 + SKIP(return, "Skipping test since %s does not exist", rtc_file); 344 + ASSERT_NE(-1, self->fd); 368 345 369 346 rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time); 370 347 ASSERT_NE(-1, rc);
+2 -2
tools/testing/selftests/splice/short_splice_read.sh
··· 127 127 if ! [ -d /sys/module/test_module/sections ] ; then 128 128 expect_success "test_module kernel module load" modprobe test_module 129 129 fi 130 - expect_failure "kernfs attr splice" test_splice /sys/module/test_module/coresize 131 - expect_failure "kernfs binattr splice" test_splice /sys/module/test_module/sections/.init.text 130 + expect_success "kernfs attr splice" test_splice /sys/module/test_module/coresize 131 + expect_success "kernfs binattr splice" test_splice /sys/module/test_module/sections/.init.text 132 132 133 133 exit $ret
+1 -1
tools/testing/selftests/tpm2/Makefile
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 2 include ../lib.mk 3 3 4 - TEST_PROGS := test_smoke.sh test_space.sh 4 + TEST_PROGS := test_smoke.sh test_space.sh test_async.sh 5 5 TEST_PROGS_EXTENDED := tpm2.py tpm2_tests.py
+10
tools/testing/selftests/tpm2/test_async.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 3 + 4 + # Kselftest framework requirement - SKIP code is 4. 5 + ksft_skip=4 6 + 7 + [ -e /dev/tpm0 ] || exit $ksft_skip 8 + [ -e /dev/tpmrm0 ] || exit $ksft_skip 9 + 10 + python3 -m unittest -v tpm2_tests.AsyncTest
-1
tools/testing/selftests/tpm2/test_smoke.sh
··· 7 7 [ -e /dev/tpm0 ] || exit $ksft_skip 8 8 9 9 python3 -m unittest -v tpm2_tests.SmokeTest 10 - python3 -m unittest -v tpm2_tests.AsyncTest
+4
tools/testing/selftests/vDSO/vdso_test_getcpu.c
··· 14 14 #include "../kselftest.h" 15 15 #include "parse_vdso.h" 16 16 17 + #if defined(__riscv) 18 + const char *version = "LINUX_4.15"; 19 + #else 17 20 const char *version = "LINUX_2.6"; 21 + #endif 18 22 const char *name = "__vdso_getcpu"; 19 23 20 24 struct getcpu_cache;
+3
tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
··· 27 27 #if defined(__aarch64__) 28 28 const char *version = "LINUX_2.6.39"; 29 29 const char *name = "__kernel_gettimeofday"; 30 + #elif defined(__riscv) 31 + const char *version = "LINUX_4.15"; 32 + const char *name = "__vdso_gettimeofday"; 30 33 #else 31 34 const char *version = "LINUX_2.6"; 32 35 const char *name = "__vdso_gettimeofday";
+101 -5
tools/testing/selftests/watchdog/watchdog-test.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Watchdog Driver Test Program 3 + * Watchdog Driver Test Program 4 + * - Tests all ioctls 5 + * - Tests Magic Close - CONFIG_WATCHDOG_NOWAYOUT 6 + * - Could be tested against softdog driver on systems that 7 + * don't have watchdog hardware. 8 + * - TODO: 9 + * - Enhance test to add coverage for WDIOC_GETTEMP. 10 + * 11 + * Reference: Documentation/watchdog/watchdog-api.rst 4 12 */ 5 13 6 14 #include <errno.h> ··· 27 19 28 20 int fd; 29 21 const char v = 'V'; 30 - static const char sopts[] = "bdehp:t:Tn:NLf:i"; 22 + static const char sopts[] = "bdehp:st:Tn:NLf:i"; 31 23 static const struct option lopts[] = { 32 24 {"bootstatus", no_argument, NULL, 'b'}, 33 25 {"disable", no_argument, NULL, 'd'}, 34 26 {"enable", no_argument, NULL, 'e'}, 35 27 {"help", no_argument, NULL, 'h'}, 36 28 {"pingrate", required_argument, NULL, 'p'}, 29 + {"status", no_argument, NULL, 's'}, 37 30 {"timeout", required_argument, NULL, 't'}, 38 31 {"gettimeout", no_argument, NULL, 'T'}, 39 32 {"pretimeout", required_argument, NULL, 'n'}, ··· 83 74 printf(" -f, --file\t\tOpen watchdog device file\n"); 84 75 printf("\t\t\tDefault is /dev/watchdog\n"); 85 76 printf(" -i, --info\t\tShow watchdog_info\n"); 77 + printf(" -s, --status\t\tGet status & supported features\n"); 86 78 printf(" -b, --bootstatus\tGet last boot status (Watchdog/POR)\n"); 87 79 printf(" -d, --disable\t\tTurn off the watchdog timer\n"); 88 80 printf(" -e, --enable\t\tTurn on the watchdog timer\n"); ··· 101 91 printf("Example: %s -t 12 -T -n 7 -N\n", progname); 102 92 } 103 93 94 + struct wdiof_status { 95 + int flag; 96 + const char *status_str; 97 + }; 98 + 99 + #define WDIOF_NUM_STATUS 8 100 + 101 + static const struct wdiof_status wdiof_status[WDIOF_NUM_STATUS] = { 102 + {WDIOF_SETTIMEOUT, "Set timeout (in seconds)"}, 103 + {WDIOF_MAGICCLOSE, "Supports magic close char"}, 104 + {WDIOF_PRETIMEOUT, "Pretimeout (in seconds), get/set"}, 105 + {WDIOF_ALARMONLY, "Watchdog triggers a management or other external alarm not a reboot"}, 106 + {WDIOF_KEEPALIVEPING, "Keep alive ping reply"}, 107 + {WDIOS_DISABLECARD, "Turn off the watchdog timer"}, 108 + {WDIOS_ENABLECARD, "Turn on the watchdog timer"}, 109 + {WDIOS_TEMPPANIC, "Kernel panic on temperature trip"}, 110 + }; 111 + 112 + static void print_status(int flags) 113 + { 114 + int wdiof = 0; 115 + 116 + if (flags == WDIOS_UNKNOWN) { 117 + printf("Unknown status error from WDIOC_GETSTATUS\n"); 118 + return; 119 + } 120 + 121 + for (wdiof = 0; wdiof < WDIOF_NUM_STATUS; wdiof++) { 122 + if (flags & wdiof_status[wdiof].flag) 123 + printf("Support/Status: %s\n", 124 + wdiof_status[wdiof].status_str); 125 + } 126 + } 127 + 128 + #define WDIOF_NUM_BOOTSTATUS 7 129 + 130 + static const struct wdiof_status wdiof_bootstatus[WDIOF_NUM_BOOTSTATUS] = { 131 + {WDIOF_OVERHEAT, "Reset due to CPU overheat"}, 132 + {WDIOF_FANFAULT, "Fan failed"}, 133 + {WDIOF_EXTERN1, "External relay 1"}, 134 + {WDIOF_EXTERN2, "External relay 2"}, 135 + {WDIOF_POWERUNDER, "Power bad/power fault"}, 136 + {WDIOF_CARDRESET, "Card previously reset the CPU"}, 137 + {WDIOF_POWEROVER, "Power over voltage"}, 138 + }; 139 + 140 + static void print_boot_status(int flags) 141 + { 142 + int wdiof = 0; 143 + 144 + if (flags == WDIOF_UNKNOWN) { 145 + printf("Unknown flag error from WDIOC_GETBOOTSTATUS\n"); 146 + return; 147 + } 148 + 149 + if (flags == 0) { 150 + printf("Last boot is caused by: Power-On-Reset\n"); 151 + return; 152 + } 153 + 154 + for (wdiof = 0; wdiof < WDIOF_NUM_BOOTSTATUS; wdiof++) { 155 + if (flags & wdiof_bootstatus[wdiof].flag) 156 + printf("Last boot is caused by: %s\n", 157 + wdiof_bootstatus[wdiof].status_str); 158 + } 159 + } 160 + 104 161 int main(int argc, char *argv[]) 105 162 { 106 163 int flags; ··· 177 100 int oneshot = 0; 178 101 char *file = "/dev/watchdog"; 179 102 struct watchdog_info info; 103 + int temperature; 180 104 181 105 setbuf(stdout, NULL); 182 106 ··· 218 140 oneshot = 1; 219 141 ret = ioctl(fd, WDIOC_GETBOOTSTATUS, &flags); 220 142 if (!ret) 221 - printf("Last boot is caused by: %s.\n", (flags != 0) ? 222 - "Watchdog" : "Power-On-Reset"); 143 + print_boot_status(flags); 223 144 else 224 145 printf("WDIOC_GETBOOTSTATUS error '%s'\n", strerror(errno)); 225 146 break; ··· 247 170 if (!ping_rate) 248 171 ping_rate = DEFAULT_PING_RATE; 249 172 printf("Watchdog ping rate set to %u seconds.\n", ping_rate); 173 + break; 174 + case 's': 175 + flags = 0; 176 + oneshot = 1; 177 + ret = ioctl(fd, WDIOC_GETSTATUS, &flags); 178 + if (!ret) 179 + print_status(flags); 180 + else 181 + printf("WDIOC_GETSTATUS error '%s'\n", strerror(errno)); 182 + ret = ioctl(fd, WDIOC_GETTEMP, &temperature); 183 + if (ret) 184 + printf("WDIOC_GETTEMP: '%s'\n", strerror(errno)); 185 + else 186 + printf("Temperature %d\n", temperature); 187 + 250 188 break; 251 189 case 't': 252 190 flags = strtoul(optarg, NULL, 0); ··· 320 228 printf(" identity:\t\t%s\n", info.identity); 321 229 printf(" firmware_version:\t%u\n", 322 230 info.firmware_version); 323 - printf(" options:\t\t%08x\n", info.options); 231 + print_status(info.options); 324 232 break; 325 233 326 234 default: ··· 341 249 sleep(ping_rate); 342 250 } 343 251 end: 252 + /* 253 + * Send specific magic character 'V' just in case Magic Close is 254 + * enabled to ensure watchdog gets disabled on close. 255 + */ 344 256 ret = write(fd, &v, 1); 345 257 if (ret < 0) 346 258 printf("Stopping watchdog ticks failed (%d)...\n", errno);