mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-08-16 23:51:44 +00:00

Commit0b631ed3ce
("kselftest: cpufreq: Add RTC wakeup alarm") added support for automatic wakeup in the suspend routine of the cpufreq kselftest by using rtcwake, however it left the manual power state change in the common path. The end result is that when running the cpufreq kselftest with '-t suspend_rtc' or '-t hibernate_rtc', the system will go to sleep and be woken up by the RTC, but then immediately go to sleep again with no wakeup programmed, so it will sleep forever in an automated testing setup. Fix this by moving the manual power state change so that it only happens when not using rtcwake. Link: https://lore.kernel.org/r/20250430-ksft-cpufreq-suspend-rtc-double-fix-v1-1-dc17a729c5a7@collabora.com Fixes:0b631ed3ce
("kselftest: cpufreq: Add RTC wakeup alarm") Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
265 lines
5.0 KiB
Bash
Executable File
265 lines
5.0 KiB
Bash
Executable File
#!/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:"
|
|
#file is readable ?
|
|
local rfile=$(ls -l $1/$file | awk '$1 ~ /^.*r.*/ { print $NF; }')
|
|
|
|
if [ ! -z $rfile ]; then
|
|
cat $1/$file
|
|
else
|
|
printf "$file is not readable\n"
|
|
fi
|
|
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 readable and writable ?
|
|
local rwfile=$(ls -l $1/$file | awk '$1 ~ /^.*rw.*/ { print $NF; }')
|
|
|
|
if [ ! -z $rwfile ]; 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
|
|
ktap_exit_fail_msg "No cpu is managed by cpufreq core, exiting\n"
|
|
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"
|
|
|
|
if [ "$3" = "rtc" ]; then
|
|
if ! command -v rtcwake &> /dev/null; then
|
|
printf "rtcwake could not be found, please install it.\n"
|
|
return 1
|
|
fi
|
|
|
|
rtcwake -m $filename -s 15
|
|
|
|
if [ $? -ne 0 ]; then
|
|
printf "Failed to suspend using RTC wake alarm\n"
|
|
return 1
|
|
fi
|
|
else
|
|
echo $filename > $SYSFS/power/state
|
|
fi
|
|
|
|
printf "Came out of $1\n"
|
|
|
|
printf "Do basic tests after finishing $1 to verify cpufreq state\n\n"
|
|
cpufreq_basic_tests
|
|
done
|
|
fi
|
|
}
|