1#!/bin/bash
2
3# Cycle the CPUs through various frequencies.
4
5# Copyright (C) 2003-2006 IBM
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15# General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20# 02111-1307, USA.
21
22
23# Do any CPU support cpufreq?
24#CPUFREQ_ENABLED_CPUS=`/bin/ls -lad /sys/devices/system/cpu/cpu*/cpufreq 2> /dev/null | wc -l`
25
26#if [ "$CPUFREQ_ENABLED_CPUS" -lt 1 ]; then
27#	echo "None of your CPUs support cpufreq.  Bye."
28#	exit 255
29#fi
30
31# Turn on acpi_pstate_strict to ensure that state transitions actually happen...
32if [ -f /sys/module/acpi_cpufreq/parameters/acpi_pstate_strict ]; then
33	echo 1 > /sys/module/acpi_cpufreq/parameters/acpi_pstate_strict
34fi
35if [ -f /sys/module/acpi/parameters/acpi_pstate_strict ]; then
36	echo 1 > /sys/module/acpi/parameters/acpi_pstate_strict
37fi
38
39# First, knock off any powersaving daemons...
40for i in `ls /etc/init.d/*powernow /etc/init.d/*cpuspeed* /etc/init.d/*powersave* 2> /dev/null`; do
41	"$i" stop
42done
43
44# Ensure that we have the userspace governor running
45for i in /sys/devices/system/cpu/cpu*; do
46	echo userspace > "$i/cpufreq/scaling_governor"
47done
48
49# Trap ^C
50trap 'kill -9 `pgrep -P $$` `pgrep cpufreq.bin` 2> /dev/null; exit 0' 1 2 15
51
52# Did we see any failures?
53LOGFILE=/proc/$$/fd/1
54OLD_ERRORS=`egrep -ic "(error|fail|invalid|denied|cannot)" $LOGFILE`
55
56# For all CPUs with cpufreq: remove CPUs that are locked with another.
57function find_cpufreq_cpus() {
58	for cpu in `ls -d /sys/devices/system/cpu/cpu*/cpufreq 2> /dev/null`; do
59		# Locked CPUs are done with symlinks in 2.6.14.
60		if [ -L "$cpu" ]; then
61			continue;
62		fi
63
64		CPU_NUM=`dirname $cpu | sed -e 's/.*cpu//g'`
65		MATCHES=`(cat /sys/devices/system/cpu/cpu*/cpufreq/affected_cpus /dev/null 2> /dev/null | while read car cdr; do echo $cdr; done) | grep "^$CPU_NUM$" -c`
66		if [ $MATCHES -eq 0 ]; then
67			echo $CPU_NUM
68		fi
69	done
70}
71
72# Find the frequencies for a given CPU
73function find_cpu_frequencies() {
74	i="/sys/devices/system/cpu/cpu$1"
75
76	if [ -f "$i/cpufreq/scaling_available_frequencies" ]; then
77		cat "$i/cpufreq/scaling_available_frequencies"
78	else
79		cat "$i/cpufreq/scaling_min_freq" "$i/cpufreq/scaling_max_freq"
80	fi
81}
82
83# Figure out which CPUs have cpufreq support.
84find_cpufreq_cpus | while read f; do
85	echo Starting CPU frequency testing on CPU $f
86	i=/sys/devices/system/cpu/cpu$f
87
88	# Does this CPU have cpufreq?
89	if [ ! -d "$i/cpufreq/" ]; then
90		continue;
91	fi
92
93	# Kick off the test.
94	"$POUNDER_HOME/timed_loop" 900 "$POUNDER_SRCDIR/cpufreq/cpufreq.bin" "$i/cpufreq/scaling_setspeed" 10000 $f `find_cpu_frequencies $f` &
95done
96
97# Wait for this to finish
98while [ `pgrep cpufreq.bin | wc -l` -gt 0 ]; do
99	sleep 5
100done
101
102# Did we see any failures?
103NEW_ERRORS=`egrep -ic "(error|fail|invalid|denied|cannot)" $LOGFILE`
104ERRORS=$(( NEW_ERRORS - OLD_ERRORS ))
105if [ $ERRORS -eq 255 ]; then
106	ERRORS=254
107fi
108
109# Failures will show up in the test output.  Or better yet,
110# panic/oops/BUG the machine.
111exit $ERRORS
112