From: Omar Sandoval Date: Mon, 11 Jun 2018 18:31:57 +0000 (-0700) Subject: block/008: don't try to offline all CPUs if all CPUs are hotpluggable X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=8de43b4b284cc8eaba0bb0a04604089737b3e8b5;p=users%2Fsagi%2Fblktests.git block/008: don't try to offline all CPUs if all CPUs are hotpluggable Chen Rong reported that if CPU0 is hotpluggable (because we booted with cpu0_hotplug or CONFIG_BOOTPARAM_HOTPLUG_CPU0 was enabled), block/008 can try to offline all CPUs at once, which isn't allowed. Fix it by repeatedly offlining as many CPUs as is allowed and onlining all CPUs, instead of the previous approach of randomly onlining/offlining. This is better than the previous approach because we won't try to online already online CPUs and offline already offline CPUs. Closes #23. Reported-by: Chen Rong Signed-off-by: Omar Sandoval --- diff --git a/common/cpuhotplug b/common/cpuhotplug index 6a790fe..70b284f 100644 --- a/common/cpuhotplug +++ b/common/cpuhotplug @@ -17,13 +17,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Also initializes the HOTPLUGGABLE_CPUS array. +# Also initializes the ALL_CPUS and HOTPLUGGABLE_CPUS arrays. _have_cpu_hotplug() { + ALL_CPUS=() HOTPLUGGABLE_CPUS=() CPUS_ONLINE_SAVED=() local cpu_dir cpu for cpu_dir in /sys/devices/system/cpu/cpu+([0-9]); do + ALL_CPUS+=("$cpu") if [[ -w ${cpu_dir}/online ]]; then cpu="${cpu_dir#/sys/devices/system/cpu/cpu}" HOTPLUGGABLE_CPUS+=("$cpu") @@ -31,7 +33,7 @@ _have_cpu_hotplug() { fi done - if [[ ${#HOTPLUGGABLE_CPUS[@]} -eq 0 ]]; then + if [[ ${#ALL_CPUS[@]} -eq 1 || ${#HOTPLUGGABLE_CPUS[@]} -eq 0 ]]; then SKIP_REASON="CPU hotplugging is not supported" return 1 fi @@ -40,10 +42,10 @@ _have_cpu_hotplug() { _online_cpu() { RESTORE_CPUS_ONLINE=1 - echo 1 >"/sys/devices/system/cpu/cpu$1/online" + echo 1 > "/sys/devices/system/cpu/cpu$1/online" } _offline_cpu() { RESTORE_CPUS_ONLINE=1 - echo 0 >"/sys/devices/system/cpu/cpu$1/online" + echo 0 > "/sys/devices/system/cpu/cpu$1/online" } diff --git a/tests/block/008 b/tests/block/008 index db2a72a..4534dc3 100755 --- a/tests/block/008 +++ b/tests/block/008 @@ -38,14 +38,45 @@ test_device() { # start fio job _run_fio_rand_io --filename="$TEST_DEV" --size="$size" & - # while job is running, hotplug CPUs randomly - while kill -0 $! 2>/dev/null; do - idx=$((RANDOM % ${#HOTPLUGGABLE_CPUS[@]})) - if (( RANDOM % 2 )); then - _online_cpu "${HOTPLUGGABLE_CPUS[$idx]}" + local online_cpus=() + local offline_cpus=() + local offlining=1 + local max_offline=${#HOTPLUGGABLE_CPUS[@]} + if [[ ${#HOTPLUGGABLE_CPUS[@]} -eq ${#ALL_CPUS[@]} ]]; then + (( max_offline-- )) + fi + for cpu in "${HOTPLUGGABLE_CPUS[@]}"; do + if (( "$(cat "/sys/devices/system/cpu/cpu${cpu}/online")" )); then + online_cpus+=("$cpu") + else + offline_cpus+=("$cpu") + fi + done + + # while job is running, hotplug CPUs + while kill -0 $! 2> /dev/null; do + if (( offlining && ${#offline_cpus[@]} == max_offline )); then + offlining=0 + elif (( ! offlining && ${#online_cpus[@]} == ${#HOTPLUGGABLE_CPUS[@]} )); then + offlining=1 + fi + + if (( offlining )); then + idx=$((RANDOM % ${#online_cpus[@]})) + echo "offlining $idx (online=${online_cpus[@]} offline=${offline_cpus[@]})" >> /dev/kmsg + _offline_cpu "${online_cpus[$idx]}" + offline_cpus+=("${online_cpus[$idx]}") + unset online_cpus[$idx] + online_cpus=("${online_cpus[@]}") else - _offline_cpu "${HOTPLUGGABLE_CPUS[$idx]}" + idx=$((RANDOM % ${#offline_cpus[@]})) + echo "onlining $idx (online=${online_cpus[@]} offline=${offline_cpus[@]})" >> /dev/kmsg + _online_cpu "${offline_cpus[$idx]}" + online_cpus+=("${offline_cpus[$idx]}") + unset offline_cpus[$idx] + offline_cpus=("${offline_cpus[@]}") fi + sleep .2 done