From 530ca6825b0df322ad979497d55ecf3902e115ed Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:45:26 +0200 Subject: [PATCH 1/5] Store disabled CPUs We will use those later for a report and to not duplicate the method of disabling. --- provision-contest/disable-turboboost_ht | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/provision-contest/disable-turboboost_ht b/provision-contest/disable-turboboost_ht index ce41e815..07f6d792 100755 --- a/provision-contest/disable-turboboost_ht +++ b/provision-contest/disable-turboboost_ht @@ -4,6 +4,13 @@ set -eu -o pipefail shopt -s extglob declare -A core_ids +declare -a disabled_cores + +disable_cpu () { + cpu="$1" + echo 0 > $cpu/online + disabled_cores+=("${cpu##*/}") +} # shellcheck disable=SC2012 for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do @@ -41,7 +48,7 @@ for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do # 'delimiter'. core_id=$(cat $cpu/topology/core_id | tr -d '\n')'-'$(cat $cpu/topology/physical_package_id | tr -d '\n') if [[ ${core_ids[$core_id]:-} ]]; then - echo 0 > $cpu/online + disable_cpu $cpu else core_ids[$core_id]=1 fi From 8ce7ab7ab3ce6727e5d12818d07c54ddc2bdcacf Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Wed, 30 Jul 2025 19:13:44 +0200 Subject: [PATCH 2/5] Store the isolated cores for ansible This is defence in depth by disallowing the kernel to schedule work on the online cpu's before the script disables the CPU's. The script can fail when the CPU taken down is currently working on something. --- provision-contest/disable-turboboost_ht | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/provision-contest/disable-turboboost_ht b/provision-contest/disable-turboboost_ht index 07f6d792..1d6739b5 100755 --- a/provision-contest/disable-turboboost_ht +++ b/provision-contest/disable-turboboost_ht @@ -12,6 +12,8 @@ disable_cpu () { disabled_cores+=("${cpu##*/}") } +store_isolcpus_fact="/var/tmp/isolcpus" + # shellcheck disable=SC2012 for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do [[ $(basename $cpu) =~ ^cpu[0-9]+$ ]] || continue @@ -54,6 +56,11 @@ for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do fi done +if [ -n "${store_isolcpus_fact}" ]; then + csv_string=$(IFS=, ; echo "${disabled_cores[*]}") + echo "$csv_string" > "$store_isolcpus_fact" +fi + DIR_INTEL=/sys/devices/system/cpu/intel_pstate DIR_AMD=/sys/devices/system/cpu/cpufreq if [ -d $DIR_INTEL ]; then From f95bb4c7758dd33fb79f151368ab4992166300b1 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:55:32 +0200 Subject: [PATCH 3/5] Clarify the package/socket usage Package is more correct but socket is better known. Also fixed a typo. --- provision-contest/disable-turboboost_ht | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/provision-contest/disable-turboboost_ht b/provision-contest/disable-turboboost_ht index 1d6739b5..f077ee5c 100755 --- a/provision-contest/disable-turboboost_ht +++ b/provision-contest/disable-turboboost_ht @@ -41,10 +41,10 @@ for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do chmod a-w $cpu/cpufreq/scaling_{max,min}_freq fi - # Disable all but one thread on each core. Both core_id and physical_package_id are - # numbers it must be ensured that for the following examples are seen as distinct: + # Disable all but one thread on each core per socket. Both core_id and physical_package_id + # are numbers so it must be ensured that for the following examples are seen as distinct: # - core_id=1, physical_package=11 - # - core_id=11, physycal_package=1 + # - core_id=11, physical_package=1 # Simple concatenation would result in the string '111' for both cores. Though `cat` # adds a newline after each file, we do not want to rely on `cat` to always add this # 'delimiter'. From 658a63ea9c0bbff7440e4efb8373bb499fd7cc4f Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Tue, 29 Jul 2025 22:14:33 +0200 Subject: [PATCH 4/5] Consider ARM processors The boost exists for asahi@M1 laptops but not on a raspberry with ARMv7. --- provision-contest/disable-turboboost_ht | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/provision-contest/disable-turboboost_ht b/provision-contest/disable-turboboost_ht index f077ee5c..ef535ee1 100755 --- a/provision-contest/disable-turboboost_ht +++ b/provision-contest/disable-turboboost_ht @@ -63,6 +63,8 @@ fi DIR_INTEL=/sys/devices/system/cpu/intel_pstate DIR_AMD=/sys/devices/system/cpu/cpufreq +# Same for some ARM CPUs +FILE_AMD=$DIR_AMD/boost if [ -d $DIR_INTEL ]; then # now disable turbo boost FILE=$DIR_INTEL/no_turbo @@ -75,11 +77,10 @@ if [ -d $DIR_INTEL ]; then # increase freq from powersaving to normal, but don't overclock echo 100 > $DIR_INTEL/min_perf_pct echo 100 > $DIR_INTEL/max_perf_pct -elif [ -d $DIR_AMD ]; then +elif [ -f $FILE_AMD ]; then # now disable boosting - FILE=$DIR_AMD/boost - echo -n 0 > $FILE || echo "Could not write to '$FILE', ignoring for now..." - if [ $(cat $FILE) -ne 0 ]; then + echo -n 0 > $FILE_AMD || echo "Could not write to '$FILE_AMD', ignoring for now..." + if [ $(cat $FILE_AMD) -ne 0 ]; then echo "Error: turboboost still enabled!" exit 1 fi From 1eb5b513907f0d25bdac5828a39772d5144aa35e Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Tue, 29 Jul 2025 21:40:06 +0200 Subject: [PATCH 5/5] Disable efficiency cores Also clarified the package/socket as package is more correct but socket is better known and fixed a typo. --- provision-contest/disable-turboboost_ht | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/provision-contest/disable-turboboost_ht b/provision-contest/disable-turboboost_ht index ef535ee1..bca9112c 100755 --- a/provision-contest/disable-turboboost_ht +++ b/provision-contest/disable-turboboost_ht @@ -14,6 +14,14 @@ disable_cpu () { store_isolcpus_fact="/var/tmp/isolcpus" +# Learn all efficency cores if they exist +cpu_list=() +if [ -f /sys/devices/cpu_atom/cpus ]; then + range="$(cat /sys/devices/cpu_atom/cpus)" + IFS='-' read -r start end <<< "$range" + cpu_list=($(eval echo {$start..$end})) +fi + # shellcheck disable=SC2012 for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do [[ $(basename $cpu) =~ ^cpu[0-9]+$ ]] || continue @@ -49,6 +57,20 @@ for cpu in $(ls -1d /sys/devices/system/cpu/cpu* | sort --version-sort) ; do # adds a newline after each file, we do not want to rely on `cat` to always add this # 'delimiter'. core_id=$(cat $cpu/topology/core_id | tr -d '\n')'-'$(cat $cpu/topology/physical_package_id | tr -d '\n') + + # Disable all efficiency cores + found=0 + for efficiency_core in "${cpu_list[@]}"; do + if [[ "$cpu" == "/sys/devices/system/cpu/cpu$efficiency_core" ]]; then + disable_cpu $cpu + found=1 + break + fi + done + if [ "$found" -eq "1" ]; then + continue + fi + if [[ ${core_ids[$core_id]:-} ]]; then disable_cpu $cpu else