config/compute-huge/compute-huge/set-cpu-wakeup-latency.sh

91 lines
2.9 KiB
Bash

#!/bin/bash
#
# Copyright (c) 2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Purpose: set PM QoS resume latency constraints for CPUs.
# Usage: /usr/bin/set-cpu-wakeup-latency.sh policy cpulist
# policy may be either "low" or "high" to set appropriate latency.
# "low" means HALT (C1) is the deepest C-state we allow the CPU to enter.
# "high" means we allow the CPU to sleep as deeply as possible.
# cpulist is for specifying a numerical list of processors.
# It may contain multiple items, separated by comma, and ranges.
# For example, 0,5,7,9-11.
# Define minimal path
PATH=/bin:/usr/bin:/usr/local/bin
LOG_FUNCTIONS=${LOG_FUNCTIONS:-"/etc/init.d/log_functions.sh"}
CPUMAP_FUNCTIONS=${CPUMAP_FUNCTIONS:-"/etc/init.d/cpumap_functions.sh"}
[[ -e ${LOG_FUNCTIONS} ]] && source ${LOG_FUNCTIONS}
[[ -e ${CPUMAP_FUNCTIONS} ]] && source ${CPUMAP_FUNCTIONS}
if [ $UID -ne 0 ]; then
log_error "$0 requires root or sudo privileges"
exit 1
fi
if [ "$#" -ne 2 ]; then
log_error "$0 requires policy and cpulist parameters"
exit 1
fi
POLICY=$1
CPU_LIST=$2
NUMBER_OF_CPUS=$(getconf _NPROCESSORS_CONF 2>/dev/null)
STATUS=1
for CPU_NUM in $(expand_sequence "$CPU_LIST" " ")
do
# Check that we are not setting PM QoS policy for non-existing CPU
if [ "$CPU_NUM" -lt "0" ] || [ "$CPU_NUM" -ge "$NUMBER_OF_CPUS" ]; then
log_error "CPU number ${CPU_NUM} is invalid, available CPUs are 0-${NUMBER_OF_CPUS-1}"
exit 1
fi
# Obtain CPU wakeup latencies for all C-states available starting from operating state to deepest sleep
declare -a LIMITS=()
LIMITS+=($(cat /sys/devices/system/cpu/cpu${CPU_NUM}/cpuidle/state*/latency 2>/dev/null | xargs | sort))
if [ ${#LIMITS[@]} -eq 0 ]; then
log_debug "Failed to get PM QoS latency limits for CPU ${CPU_NUM}"
fi
# Select appropriate CPU wakeup latency based on "low" or "high" policy
case "${POLICY}" in
"low")
# Get first sleep state for "low" policy
if [ ${#LIMITS[@]} -eq 0 ]; then
LATENCY=1
else
LATENCY=${LIMITS[1]}
fi
;;
"high")
# Get deepest sleep state for "high" policy
if [ ${#LIMITS[@]} -eq 0 ]; then
LATENCY=1000
else
LATENCY=${LIMITS[${#LIMITS[@]}-1]}
fi
;;
*)
log_error "Policy is invalid, can be either low or high"
exit 1
esac
# Set the latency for paricular CPU
echo ${LATENCY} > /sys/devices/system/cpu/cpu${CPU_NUM}/power/pm_qos_resume_latency_us 2>/dev/null
RET_VAL=$?
if [ ${RET_VAL} -ne 0 ]; then
log_error "Failed to set PM QoS latency for CPU ${CPU_NUM}, rc=${RET_VAL}"
continue
else
log_debug "Succesfully set PM QoS latency for CPU ${CPU_NUM}, rc=${RET_VAL}"
STATUS=0
fi
done
exit ${STATUS}