fwt_software/tools/thermal-sim/cap-cpu.sh

39 lines
1.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Cap the CPU clock, to see how the program copes with a CPU slowed to stay cool.
#
# sudo tools/thermal-sim/cap-cpu.sh 800 # every core at most 800 MHz
# sudo tools/thermal-sim/cap-cpu.sh restore # back to what it was
#
# Writes scaling_max_freq on every core. The values found the first time are
# kept in /run/fgc-cap-cpu.saved, so `restore` puts back the real ones however
# many caps were set in between. A reboot also clears the cap.
set -euo pipefail
saved=/run/fgc-cap-cpu.saved
cpus=(/sys/devices/system/cpu/cpu[0-9]*/cpufreq)
usage() { echo "usage: $0 <MHz> | restore" >&2; exit 2; }
[[ $# -eq 1 ]] || usage
[[ $EUID -eq 0 ]] || { echo "$0: needs root (sudo)" >&2; exit 1; }
[[ -e ${cpus[0]}/scaling_max_freq ]] || { echo "$0: no cpufreq on this machine" >&2; exit 1; }
if [[ $1 == restore ]]; then
[[ -f $saved ]] || { echo "nothing to restore (no cap set since boot)"; exit 0; }
while read -r dir khz; do echo "$khz" > "$dir/scaling_max_freq"; done < "$saved"
rm -f "$saved"
echo "CPU clock limits restored"
exit 0
fi
[[ $1 =~ ^[0-9]+$ ]] || usage
khz=$(( $1 * 1000 ))
if [[ ! -f $saved ]]; then
for d in "${cpus[@]}"; do echo "$d $(cat "$d/scaling_max_freq")"; done > "$saved"
fi
for d in "${cpus[@]}"; do
min=$(cat "$d/cpuinfo_min_freq")
(( khz < min )) && { echo "$0: $1 MHz is under this CPU's minimum ($((min / 1000)) MHz)" >&2; exit 1; }
echo "$khz" > "$d/scaling_max_freq"
done
echo "every core capped at $1 MHz ('$0 restore' to undo)"