Spdk/test/scheduler/governor.sh
Michal Berger 92e49c0044 test/scheduler: Wait for a bit for the governor to change the freq
Issues like https://github.com/spdk/spdk/issues/1784 showed that
governor may need some more time to properly adjust cpufreq's sysfs
knobs. In case we see that frequency setting hasn't changed after
given iteration, wait for 0.5s to make sure it finally settles.

Signed-off-by: Michal Berger <michalx.berger@intel.com>
Change-Id: Ibf25d0d1962bf2b07b13d60d6096c5cc185c1279
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6283
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Community-CI: Mellanox Build Bot
2021-02-09 11:24:22 +00:00

138 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
testdir=$(readlink -f "$(dirname "$0")")
rootdir=$(readlink -f "$testdir/../../")
source "$rootdir/test/common/autotest_common.sh"
source "$testdir/common.sh"
trap 'killprocess "$spdk_pid" || :; restore_cpufreq' EXIT
restore_cpufreq() {
local cpu
for cpu in "$spdk_main_core" "${cpus[@]}"; do
set_cpufreq "$cpu" "$main_core_min_freq" "$main_core_max_freq"
set_cpufreq_governor "$cpu" "$initial_main_core_governor"
done
}
update_main_core_cpufreq() {
map_cpufreq
main_core_driver=${cpufreq_drivers[spdk_main_core]}
main_core_governor=${cpufreq_governors[spdk_main_core]}
main_core_set_min_freq=${cpufreq_min_freqs[spdk_main_core]}
main_core_set_cur_freq=${cpufreq_cur_freqs[spdk_main_core]}
main_core_set_max_freq=${cpufreq_max_freqs[spdk_main_core]}
if ((${#main_core_freqs[@]} == 0)); then
main_core_freqs=("${!cpufreq_available_freqs[spdk_main_core]}")
main_core_max_freq=${main_core_freqs[0]}
main_core_min_freq=${main_core_freqs[-1]}
fi
if ((${#main_core_freqs_map[@]} == 0)); then
fold_list_onto_array main_core_freqs_map "${main_core_freqs[@]}"
fi
case "$main_core_driver" in
acpi-cpufreq) main_core_setspeed=${cpufreq_setspeed[spdk_main_core]} ;;
intel_pstate | intel_cpufreq) main_core_setspeed=$main_core_set_max_freq ;;
esac
}
verify_dpdk_governor() {
xtrace_disable
# Run the app and see if DPDK's PM subsystem is doing the proper thing. Aim at the main core.
# What we expect to happen is based mainly on what cpufreq driver is in use. The main assumption
# is that with all SPDK threads being idle the governor should start lowering the frequency for
# the main core.
# - acpi-cpufreq:
# - governor set to userspace
# - lowering setspeed for the main core
# - having setspeed at lowest supported frequency
# - intel_pstate (active or passive)
# - governor set to performance
# - lowering max_freq and min_freq for the main core
# - having max_freq and min_freq at lowest supported frequency
local -g cpus
local dir_map
dir_map[0]="<"
dir_map[1]=">"
dir_map[2]="=="
fold_list_onto_array cpus $(parse_cpu_list <(echo "$spdk_cpus_csv"))
# Get rid of the main core
unset -v "cpus[spdk_main_core]"
local samples=0 all_set=0 dir=-1 old_main_core_setspeed=0
exec_under_dynamic_scheduler "${SPDK_APP[@]}" -m "$spdk_cpusmask" --main-core "$spdk_main_core"
while ((all_set == 0 && samples++ <= 50)); do
update_main_core_cpufreq
if [[ $main_core_setspeed == "<unsupported>" ]]; then
# governor hasn't taken over yet, skip this sample
printf 'Waiting for DPDK governor to take over...\n'
continue
fi
if ((main_core_setspeed > old_main_core_setspeed)); then
dir=1
elif ((main_core_setspeed < old_main_core_setspeed)); then
dir=0
elif ((main_core_setspeed == old_main_core_setspeed)); then
# Frequency didn't change, skip and wait for a bit
sleep 0.5s
continue
fi
case "$main_core_driver" in
acpi-cpufreq)
[[ $main_core_governor == userspace ]] \
&& [[ -n ${main_core_freqs_map[main_core_setspeed]} ]] \
&& ((main_core_setspeed == main_core_freqs[-1])) \
&& ((dir == 0))
;;
intel_pstate | intel_cpufreq)
[[ $main_core_governor == performance ]] \
&& [[ -n ${main_core_freqs_map[main_core_setspeed]} ]] \
&& ((main_core_setspeed == main_core_freqs[-1])) \
&& ((main_core_set_max_freq == main_core_set_min_freq)) \
&& ((dir == 0))
;;
esac && all_set=1
# Print stats after first sane sample was taken
if ((old_main_core_setspeed != 0 && dir != -1)); then
# Currently, we only determine if DPDK set sysfs attributes to min frequency supported by given cpu.
# We don't act on actual frequency cpu ends up spinning at. The reason being all sibling threads of
# the main cpu would need to be adjusted manually (i.e. their cpufreq attributes) in order for freq
# to start going down. This is deemed as not necessary for the moment since the core objective of
# the test is to determine if DPDK's governor did its job, within its current scope, not how it
# impacts the system overall.
printf 'MAIN DPDK cpu%u current frequency at %u KHz (%u KHz), set frequency %u KHz %s %u KHz\n' \
"$spdk_main_core" "$main_core_set_cur_freq" "$main_core_max_freq" \
"$main_core_setspeed" "${dir_map[dir]}" "$old_main_core_setspeed"
else
printf 'Waiting for samples...\n'
fi
old_main_core_setspeed=$main_core_setspeed
done
((all_set == 1))
xtrace_restore
}
map_cpufreq
# Save initial scaling governor to restore it later on
initial_main_core_governor=${cpufreq_governors[spdk_main_core]}
verify_dpdk_governor