Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e66d5b67 authored by Viresh Kumar's avatar Viresh Kumar Committed by Shuah Khan
Browse files

selftest: cpufreq: Add support for cpufreq tests



This patch adds supports for basic cpufreq tests, which can be performed
independent of any platform.

It does basic tests for now, like
- reading all cpufreq files
- trying to update them
- switching frequencies
- switching governors

This can be extended to have more specific tests later on.

Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarShuah Khan <shuahkh@osg.samsung.com>
parent 6320303f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
TARGETS =  bpf
TARGETS += breakpoints
TARGETS += capabilities
TARGETS += cpufreq
TARGETS += cpu-hotplug
TARGETS += efivarfs
TARGETS += exec
+8 −0
Original line number Diff line number Diff line
all:

TEST_PROGS := main.sh
TEST_FILES := cpu.sh cpufreq.sh governor.sh

include ../lib.mk

clean:
+84 −0
Original line number Diff line number Diff line
#!/bin/bash
#
# 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;
}
+201 −0
Original line number Diff line number Diff line
#!/bin/bash

# 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
}
+146 −0
Original line number Diff line number Diff line
#!/bin/bash
#
# 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
}

# 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" "------------------------------------------------"
}
Loading