diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
commit | 5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch) | |
tree | a94efe259b9009378be6d90eb30d2b019d95c194 /tools/testing/selftests/cpufreq | |
parent | Initial commit. (diff) | |
download | linux-upstream/5.10.209.tar.xz linux-upstream/5.10.209.zip |
Adding upstream version 5.10.209.upstream/5.10.209upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | tools/testing/selftests/cpufreq/Makefile | 9 | ||||
-rw-r--r-- | tools/testing/selftests/cpufreq/config | 15 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/cpu.sh | 85 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/cpufreq.sh | 242 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/governor.sh | 154 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/main.sh | 198 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/module.sh | 244 | ||||
-rwxr-xr-x | tools/testing/selftests/cpufreq/special-tests.sh | 116 |
8 files changed, 1063 insertions, 0 deletions
diff --git a/tools/testing/selftests/cpufreq/Makefile b/tools/testing/selftests/cpufreq/Makefile new file mode 100644 index 000000000..c86ca8342 --- /dev/null +++ b/tools/testing/selftests/cpufreq/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +all: + +TEST_PROGS := main.sh +TEST_FILES := cpu.sh cpufreq.sh governor.sh module.sh special-tests.sh + +include ../lib.mk + +clean: diff --git a/tools/testing/selftests/cpufreq/config b/tools/testing/selftests/cpufreq/config new file mode 100644 index 000000000..27ff72ebd --- /dev/null +++ b/tools/testing/selftests/cpufreq/config @@ -0,0 +1,15 @@ +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_PI_LIST=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +CONFIG_PROVE_LOCKING=y +CONFIG_LOCKDEP=y +CONFIG_DEBUG_ATOMIC_SLEEP=y diff --git a/tools/testing/selftests/cpufreq/cpu.sh b/tools/testing/selftests/cpufreq/cpu.sh new file mode 100755 index 000000000..39fdcdfb8 --- /dev/null +++ b/tools/testing/selftests/cpufreq/cpu.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# CPU helpers + +# protect against multiple inclusion +if [ $FILE_CPU ]; then + return 0 +else + FILE_CPU=DONE +fi + +source cpufreq.sh + +for_each_cpu() +{ + cpus=$(ls $CPUROOT | grep "cpu[0-9].*") + for cpu in $cpus; do + $@ $cpu + done +} + +for_each_non_boot_cpu() +{ + cpus=$(ls $CPUROOT | grep "cpu[1-9].*") + for cpu in $cpus; do + $@ $cpu + done +} + +#$1: cpu +offline_cpu() +{ + printf "Offline $1\n" + echo 0 > $CPUROOT/$1/online +} + +#$1: cpu +online_cpu() +{ + printf "Online $1\n" + echo 1 > $CPUROOT/$1/online +} + +#$1: cpu +reboot_cpu() +{ + offline_cpu $1 + online_cpu $1 +} + +# Reboot CPUs +# param: number of times we want to run the loop +reboot_cpus() +{ + printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n" + + for i in `seq 1 $1`; do + for_each_non_boot_cpu offline_cpu + for_each_non_boot_cpu online_cpu + printf "\n" + done + + printf "\n%s\n\n" "------------------------------------------------" +} + +# Prints warning for all CPUs with missing cpufreq directory +print_unmanaged_cpus() +{ + for_each_cpu cpu_should_have_cpufreq_directory +} + +# Counts CPUs with cpufreq directories +count_cpufreq_managed_cpus() +{ + count=0; + + for cpu in `ls $CPUROOT | grep "cpu[0-9].*"`; do + if [ -d $CPUROOT/$cpu/cpufreq ]; then + let count=count+1; + fi + done + + echo $count; +} diff --git a/tools/testing/selftests/cpufreq/cpufreq.sh b/tools/testing/selftests/cpufreq/cpufreq.sh new file mode 100755 index 000000000..b583a2fb4 --- /dev/null +++ b/tools/testing/selftests/cpufreq/cpufreq.sh @@ -0,0 +1,242 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# protect against multiple inclusion +if [ $FILE_CPUFREQ ]; then + return 0 +else + FILE_CPUFREQ=DONE +fi + +source cpu.sh + + +# $1: cpu +cpu_should_have_cpufreq_directory() +{ + if [ ! -d $CPUROOT/$1/cpufreq ]; then + printf "Warning: No cpufreq directory present for $1\n" + fi +} + +cpu_should_not_have_cpufreq_directory() +{ + if [ -d $CPUROOT/$1/cpufreq ]; then + printf "Warning: cpufreq directory present for $1\n" + fi +} + +for_each_policy() +{ + policies=$(ls $CPUFREQROOT| grep "policy[0-9].*") + for policy in $policies; do + $@ $policy + done +} + +for_each_policy_concurrent() +{ + policies=$(ls $CPUFREQROOT| grep "policy[0-9].*") + for policy in $policies; do + $@ $policy & + done +} + +# $1: Path +read_cpufreq_files_in_dir() +{ + local files=`ls $1` + + printf "Printing directory: $1\n\n" + + for file in $files; do + if [ -f $1/$file ]; then + printf "$file:" + cat $1/$file + else + printf "\n" + read_cpufreq_files_in_dir "$1/$file" + fi + done + printf "\n" +} + + +read_all_cpufreq_files() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + read_cpufreq_files_in_dir $CPUFREQROOT + + printf "%s\n\n" "------------------------------------------------" +} + + +# UPDATE CPUFREQ FILES + +# $1: directory path +update_cpufreq_files_in_dir() +{ + local files=`ls $1` + + printf "Updating directory: $1\n\n" + + for file in $files; do + if [ -f $1/$file ]; then + # file is writable ? + local wfile=$(ls -l $1/$file | awk '$1 ~ /^.*w.*/ { print $NF; }') + + if [ ! -z $wfile ]; then + # scaling_setspeed is a special file and we + # should skip updating it + if [ $file != "scaling_setspeed" ]; then + local val=$(cat $1/$file) + printf "Writing $val to: $file\n" + echo $val > $1/$file + fi + fi + else + printf "\n" + update_cpufreq_files_in_dir "$1/$file" + fi + done + + printf "\n" +} + +# Update all writable files with their existing values +update_all_cpufreq_files() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + update_cpufreq_files_in_dir $CPUFREQROOT + + printf "%s\n\n" "------------------------------------------------" +} + + +# CHANGE CPU FREQUENCIES + +# $1: policy +find_current_freq() +{ + cat $CPUFREQROOT/$1/scaling_cur_freq +} + +# $1: policy +# $2: frequency +set_cpu_frequency() +{ + printf "Change frequency for $1 to $2\n" + echo $2 > $CPUFREQROOT/$1/scaling_setspeed +} + +# $1: policy +test_all_frequencies() +{ + local filepath="$CPUFREQROOT/$1" + + backup_governor $1 + + local found=$(switch_governor $1 "userspace") + if [ $found = 1 ]; then + printf "${FUNCNAME[0]}: userspace governor not available for: $1\n" + return; + fi + + printf "Switched governor for $1 to userspace\n\n" + + local freqs=$(cat $filepath/scaling_available_frequencies) + printf "Available frequencies for $1: $freqs\n\n" + + # Set all frequencies one-by-one + for freq in $freqs; do + set_cpu_frequency $1 $freq + done + + printf "\n" + + restore_governor $1 +} + +# $1: loop count +shuffle_frequency_for_all_cpus() +{ + printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n" + + for i in `seq 1 $1`; do + for_each_policy test_all_frequencies + done + printf "\n%s\n\n" "------------------------------------------------" +} + +# Basic cpufreq tests +cpufreq_basic_tests() +{ + printf "*** RUNNING CPUFREQ SANITY TESTS ***\n" + printf "====================================\n\n" + + count=$(count_cpufreq_managed_cpus) + if [ $count = 0 ]; then + printf "No cpu is managed by cpufreq core, exiting\n" + exit; + else + printf "CPUFreq manages: $count CPUs\n\n" + fi + + # Detect & print which CPUs are not managed by cpufreq + print_unmanaged_cpus + + # read/update all cpufreq files + read_all_cpufreq_files + update_all_cpufreq_files + + # hotplug cpus + reboot_cpus 5 + + # Test all frequencies + shuffle_frequency_for_all_cpus 2 + + # Test all governors + shuffle_governors_for_all_cpus 1 +} + +# Suspend/resume +# $1: "suspend" or "hibernate", $2: loop count +do_suspend() +{ + printf "** Test: Running ${FUNCNAME[0]}: Trying $1 for $2 loops **\n\n" + + # Is the directory available + if [ ! -d $SYSFS/power/ -o ! -f $SYSFS/power/state ]; then + printf "$SYSFS/power/state not available\n" + return 1 + fi + + if [ $1 = "suspend" ]; then + filename="mem" + elif [ $1 = "hibernate" ]; then + filename="disk" + else + printf "$1 is not a valid option\n" + return 1 + fi + + if [ -n $filename ]; then + present=$(cat $SYSFS/power/state | grep $filename) + + if [ -z "$present" ]; then + printf "Tried to $1 but $filename isn't present in $SYSFS/power/state\n" + return 1; + fi + + for i in `seq 1 $2`; do + printf "Starting $1\n" + echo $filename > $SYSFS/power/state + printf "Came out of $1\n" + + printf "Do basic tests after finishing $1 to verify cpufreq state\n\n" + cpufreq_basic_tests + done + fi +} diff --git a/tools/testing/selftests/cpufreq/governor.sh b/tools/testing/selftests/cpufreq/governor.sh new file mode 100755 index 000000000..fe37df79c --- /dev/null +++ b/tools/testing/selftests/cpufreq/governor.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test governors + +# protect against multiple inclusion +if [ $FILE_GOVERNOR ]; then + return 0 +else + FILE_GOVERNOR=DONE +fi + +source cpu.sh +source cpufreq.sh + +CUR_GOV= +CUR_FREQ= + +# Find governor's directory path +# $1: policy, $2: governor +find_gov_directory() +{ + if [ -d $CPUFREQROOT/$2 ]; then + printf "$CPUFREQROOT/$2\n" + elif [ -d $CPUFREQROOT/$1/$2 ]; then + printf "$CPUFREQROOT/$1/$2\n" + else + printf "INVALID\n" + fi +} + +# $1: policy +find_current_governor() +{ + cat $CPUFREQROOT/$1/scaling_governor +} + +# $1: policy +backup_governor() +{ + CUR_GOV=$(find_current_governor $1) + + printf "Governor backup done for $1: $CUR_GOV\n" + + if [ $CUR_GOV == "userspace" ]; then + CUR_FREQ=$(find_current_freq $1) + printf "Governor frequency backup done for $1: $CUR_FREQ\n" + fi + + printf "\n" +} + +# $1: policy +restore_governor() +{ + __switch_governor $1 $CUR_GOV + + printf "Governor restored for $1 to $CUR_GOV\n" + + if [ $CUR_GOV == "userspace" ]; then + set_cpu_frequency $1 $CUR_FREQ + printf "Governor frequency restored for $1: $CUR_FREQ\n" + fi + + printf "\n" +} + +# param: +# $1: policy, $2: governor +__switch_governor() +{ + echo $2 > $CPUFREQROOT/$1/scaling_governor +} + +# param: +# $1: cpu, $2: governor +__switch_governor_for_cpu() +{ + echo $2 > $CPUROOT/$1/cpufreq/scaling_governor +} + +# SWITCH GOVERNORS + +# $1: cpu, $2: governor +switch_governor() +{ + local filepath=$CPUFREQROOT/$1/scaling_available_governors + + # check if governor is available + local found=$(cat $filepath | grep $2 | wc -l) + if [ $found = 0 ]; then + echo 1; + return + fi + + __switch_governor $1 $2 + echo 0; +} + +# $1: policy, $2: governor +switch_show_governor() +{ + cur_gov=find_current_governor + if [ $cur_gov == "userspace" ]; then + cur_freq=find_current_freq + fi + + # switch governor + __switch_governor $1 $2 + + printf "\nSwitched governor for $1 to $2\n\n" + + if [ $2 == "userspace" -o $2 == "powersave" -o $2 == "performance" ]; then + printf "No files to read for $2 governor\n\n" + return + fi + + # show governor files + local govpath=$(find_gov_directory $1 $2) + read_cpufreq_files_in_dir $govpath +} + +# $1: function to be called, $2: policy +call_for_each_governor() +{ + local filepath=$CPUFREQROOT/$2/scaling_available_governors + + # Exit if cpu isn't managed by cpufreq core + if [ ! -f $filepath ]; then + return; + fi + + backup_governor $2 + + local governors=$(cat $filepath) + printf "Available governors for $2: $governors\n" + + for governor in $governors; do + $1 $2 $governor + done + + restore_governor $2 +} + +# $1: loop count +shuffle_governors_for_all_cpus() +{ + printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n" + + for i in `seq 1 $1`; do + for_each_policy call_for_each_governor switch_show_governor + done + printf "%s\n\n" "------------------------------------------------" +} diff --git a/tools/testing/selftests/cpufreq/main.sh b/tools/testing/selftests/cpufreq/main.sh new file mode 100755 index 000000000..31f8c9a76 --- /dev/null +++ b/tools/testing/selftests/cpufreq/main.sh @@ -0,0 +1,198 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +source cpu.sh +source cpufreq.sh +source governor.sh +source module.sh +source special-tests.sh + +FUNC=basic # do basic tests by default +OUTFILE=cpufreq_selftest +SYSFS= +CPUROOT= +CPUFREQROOT= + +# Kselftest framework requirement - SKIP code is 4. +ksft_skip=4 + +helpme() +{ + printf "Usage: $0 [-h] [-todg args] + [-h <help>] + [-o <output-file-for-dump>] + [-t <basic: Basic cpufreq testing + suspend: suspend/resume, + hibernate: hibernate/resume, + modtest: test driver or governor modules. Only to be used with -d or -g options, + sptest1: Simple governor switch to produce lockdep. + sptest2: Concurrent governor switch to produce lockdep. + sptest3: Governor races, shuffle between governors quickly. + sptest4: CPU hotplugs with updates to cpufreq files.>] + [-d <driver's module name: only with \"-t modtest>\"] + [-g <governor's module name: only with \"-t modtest>\"] + \n" + exit 2 +} + +prerequisite() +{ + msg="skip all tests:" + + if [ $UID != 0 ]; then + echo $msg must be run as root >&2 + exit $ksft_skip + fi + + taskset -p 01 $$ + + SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` + + if [ ! -d "$SYSFS" ]; then + echo $msg sysfs is not mounted >&2 + exit 2 + fi + + CPUROOT=$SYSFS/devices/system/cpu + CPUFREQROOT="$CPUROOT/cpufreq" + + if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then + echo $msg cpus not available in sysfs >&2 + exit 2 + fi + + if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then + echo $msg cpufreq directory not available in sysfs >&2 + exit 2 + fi +} + +parse_arguments() +{ + while getopts ht:o:d:g: arg + do + case $arg in + h) # --help + helpme + ;; + + t) # --func_type (Function to perform: basic, suspend, hibernate, modtest, sptest1/2/3/4 (default: basic)) + FUNC=$OPTARG + ;; + + o) # --output-file (Output file to store dumps) + OUTFILE=$OPTARG + ;; + + d) # --driver-mod-name (Name of the driver module) + DRIVER_MOD=$OPTARG + ;; + + g) # --governor-mod-name (Name of the governor module) + GOVERNOR_MOD=$OPTARG + ;; + + \?) + helpme + ;; + esac + done +} + +do_test() +{ + # Check if CPUs are managed by cpufreq or not + count=$(count_cpufreq_managed_cpus) + + if [ $count = 0 -a $FUNC != "modtest" ]; then + echo "No cpu is managed by cpufreq core, exiting" + exit 2; + fi + + case "$FUNC" in + "basic") + cpufreq_basic_tests + ;; + + "suspend") + do_suspend "suspend" 1 + ;; + + "hibernate") + do_suspend "hibernate" 1 + ;; + + "modtest") + # Do we have modules in place? + if [ -z $DRIVER_MOD ] && [ -z $GOVERNOR_MOD ]; then + echo "No driver or governor module passed with -d or -g" + exit 2; + fi + + if [ $DRIVER_MOD ]; then + if [ $GOVERNOR_MOD ]; then + module_test $DRIVER_MOD $GOVERNOR_MOD + else + module_driver_test $DRIVER_MOD + fi + else + if [ $count = 0 ]; then + echo "No cpu is managed by cpufreq core, exiting" + exit 2; + fi + + module_governor_test $GOVERNOR_MOD + fi + ;; + + "sptest1") + simple_lockdep + ;; + + "sptest2") + concurrent_lockdep + ;; + + "sptest3") + governor_race + ;; + + "sptest4") + hotplug_with_updates + ;; + + *) + echo "Invalid [-f] function type" + helpme + ;; + esac +} + +# clear dumps +# $1: file name +clear_dumps() +{ + echo "" > $1.txt + echo "" > $1.dmesg_cpufreq.txt + echo "" > $1.dmesg_full.txt +} + +# $1: output file name +dmesg_dumps() +{ + dmesg | grep cpufreq >> $1.dmesg_cpufreq.txt + + # We may need the full logs as well + dmesg >> $1.dmesg_full.txt +} + +# Parse arguments +parse_arguments $@ + +# Make sure all requirements are met +prerequisite + +# Run requested functions +clear_dumps $OUTFILE +do_test >> $OUTFILE.txt +dmesg_dumps $OUTFILE diff --git a/tools/testing/selftests/cpufreq/module.sh b/tools/testing/selftests/cpufreq/module.sh new file mode 100755 index 000000000..22563cd12 --- /dev/null +++ b/tools/testing/selftests/cpufreq/module.sh @@ -0,0 +1,244 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Modules specific tests cases + +# protect against multiple inclusion +if [ $FILE_MODULE ]; then + return 0 +else + FILE_MODULE=DONE +fi + +source cpu.sh +source cpufreq.sh +source governor.sh + +# Check basic insmod/rmmod +# $1: module +test_basic_insmod_rmmod() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + printf "Inserting $1 module\n" + # insert module + insmod $1 + if [ $? != 0 ]; then + printf "Insmod $1 failed\n" + exit; + fi + + printf "Removing $1 module\n" + # remove module + rmmod $1 + if [ $? != 0 ]; then + printf "rmmod $1 failed\n" + exit; + fi + + printf "\n" +} + +# Insert cpufreq driver module and perform basic tests +# $1: cpufreq-driver module to insert +# $2: If we want to play with CPUs (1) or not (0) +module_driver_test_single() +{ + printf "** Test: Running ${FUNCNAME[0]} for driver $1 and cpus_hotplug=$2 **\n\n" + + if [ $2 -eq 1 ]; then + # offline all non-boot CPUs + for_each_non_boot_cpu offline_cpu + printf "\n" + fi + + # insert module + printf "Inserting $1 module\n\n" + insmod $1 + if [ $? != 0 ]; then + printf "Insmod $1 failed\n" + return; + fi + + if [ $2 -eq 1 ]; then + # online all non-boot CPUs + for_each_non_boot_cpu online_cpu + printf "\n" + fi + + # run basic tests + cpufreq_basic_tests + + # remove module + printf "Removing $1 module\n\n" + rmmod $1 + if [ $? != 0 ]; then + printf "rmmod $1 failed\n" + return; + fi + + # There shouldn't be any cpufreq directories now. + for_each_cpu cpu_should_not_have_cpufreq_directory + printf "\n" +} + +# $1: cpufreq-driver module to insert +module_driver_test() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + # check if module is present or not + ls $1 > /dev/null + if [ $? != 0 ]; then + printf "$1: not present in `pwd` folder\n" + return; + fi + + # test basic module tests + test_basic_insmod_rmmod $1 + + # Do simple module test + module_driver_test_single $1 0 + + # Remove CPUs before inserting module and then bring them back + module_driver_test_single $1 1 + printf "\n" +} + +# find governor name based on governor module name +# $1: governor module name +find_gov_name() +{ + if [ $1 = "cpufreq_ondemand.ko" ]; then + printf "ondemand" + elif [ $1 = "cpufreq_conservative.ko" ]; then + printf "conservative" + elif [ $1 = "cpufreq_userspace.ko" ]; then + printf "userspace" + elif [ $1 = "cpufreq_performance.ko" ]; then + printf "performance" + elif [ $1 = "cpufreq_powersave.ko" ]; then + printf "powersave" + elif [ $1 = "cpufreq_schedutil.ko" ]; then + printf "schedutil" + fi +} + +# $1: governor string, $2: governor module, $3: policy +# example: module_governor_test_single "ondemand" "cpufreq_ondemand.ko" 2 +module_governor_test_single() +{ + printf "** Test: Running ${FUNCNAME[0]} for $3 **\n\n" + + backup_governor $3 + + # switch to new governor + printf "Switch from $CUR_GOV to $1\n" + switch_show_governor $3 $1 + + # try removing module, it should fail as governor is used + printf "Removing $2 module\n\n" + rmmod $2 + if [ $? = 0 ]; then + printf "WARN: rmmod $2 succeeded even if governor is used\n" + insmod $2 + else + printf "Pass: unable to remove $2 while it is being used\n\n" + fi + + # switch back to old governor + printf "Switchback to $CUR_GOV from $1\n" + restore_governor $3 + printf "\n" +} + +# Insert cpufreq governor module and perform basic tests +# $1: cpufreq-governor module to insert +module_governor_test() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + # check if module is present or not + ls $1 > /dev/null + if [ $? != 0 ]; then + printf "$1: not present in `pwd` folder\n" + return; + fi + + # test basic module tests + test_basic_insmod_rmmod $1 + + # insert module + printf "Inserting $1 module\n\n" + insmod $1 + if [ $? != 0 ]; then + printf "Insmod $1 failed\n" + return; + fi + + # switch to new governor for each cpu + for_each_policy module_governor_test_single $(find_gov_name $1) $1 + + # remove module + printf "Removing $1 module\n\n" + rmmod $1 + if [ $? != 0 ]; then + printf "rmmod $1 failed\n" + return; + fi + printf "\n" +} + +# test modules: driver and governor +# $1: driver module, $2: governor module +module_test() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n\n" + + # check if modules are present or not + ls $1 $2 > /dev/null + if [ $? != 0 ]; then + printf "$1 or $2: is not present in `pwd` folder\n" + return; + fi + + # TEST1: Insert gov after driver + # insert driver module + printf "Inserting $1 module\n\n" + insmod $1 + if [ $? != 0 ]; then + printf "Insmod $1 failed\n" + return; + fi + + # run governor tests + module_governor_test $2 + + # remove driver module + printf "Removing $1 module\n\n" + rmmod $1 + if [ $? != 0 ]; then + printf "rmmod $1 failed\n" + return; + fi + + # TEST2: Insert driver after governor + # insert governor module + printf "Inserting $2 module\n\n" + insmod $2 + if [ $? != 0 ]; then + printf "Insmod $2 failed\n" + return; + fi + + # run governor tests + module_driver_test $1 + + # remove driver module + printf "Removing $2 module\n\n" + rmmod $2 + if [ $? != 0 ]; then + printf "rmmod $2 failed\n" + return; + fi +} diff --git a/tools/testing/selftests/cpufreq/special-tests.sh b/tools/testing/selftests/cpufreq/special-tests.sh new file mode 100755 index 000000000..8d40505dc --- /dev/null +++ b/tools/testing/selftests/cpufreq/special-tests.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Special test cases reported by people + +# Testcase 1: Reported here: http://marc.info/?l=linux-pm&m=140618592709858&w=2 + +# protect against multiple inclusion +if [ $FILE_SPECIAL ]; then + return 0 +else + FILE_SPECIAL=DONE +fi + +source cpu.sh +source cpufreq.sh +source governor.sh + +# Test 1 +# $1: policy +__simple_lockdep() +{ + # switch to ondemand + __switch_governor $1 "ondemand" + + # cat ondemand files + local ondir=$(find_gov_directory $1 "ondemand") + if [ -z $ondir ]; then + printf "${FUNCNAME[0]}Ondemand directory not created, quit" + return + fi + + cat $ondir/* + + # switch to conservative + __switch_governor $1 "conservative" +} + +simple_lockdep() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n" + + for_each_policy __simple_lockdep +} + +# Test 2 +# $1: policy +__concurrent_lockdep() +{ + for i in `seq 0 100`; do + __simple_lockdep $1 + done +} + +concurrent_lockdep() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n" + + for_each_policy_concurrent __concurrent_lockdep +} + +# Test 3 +quick_shuffle() +{ + # this is called concurrently from governor_race + for I in `seq 1000` + do + echo ondemand | sudo tee $CPUFREQROOT/policy*/scaling_governor & + echo userspace | sudo tee $CPUFREQROOT/policy*/scaling_governor & + done +} + +governor_race() +{ + printf "** Test: Running ${FUNCNAME[0]} **\n" + + # run 8 concurrent instances + for I in `seq 8` + do + quick_shuffle & + done +} + +# Test 4 +# $1: cpu +hotplug_with_updates_cpu() +{ + local filepath="$CPUROOT/$1/cpufreq" + + # switch to ondemand + __switch_governor_for_cpu $1 "ondemand" + + for i in `seq 1 5000` + do + reboot_cpu $1 + done & + + local freqs=$(cat $filepath/scaling_available_frequencies) + local oldfreq=$(cat $filepath/scaling_min_freq) + + for j in `seq 1 5000` + do + # Set all frequencies one-by-one + for freq in $freqs; do + echo $freq > $filepath/scaling_min_freq + done + done + + # restore old freq + echo $oldfreq > $filepath/scaling_min_freq +} + +hotplug_with_updates() +{ + for_each_non_boot_cpu hotplug_with_updates_cpu +} |