]> www.infradead.org Git - users/sagi/blktests.git/commitdiff
block/008: don't try to offline all CPUs if all CPUs are hotpluggable
authorOmar Sandoval <osandov@fb.com>
Mon, 11 Jun 2018 18:31:57 +0000 (11:31 -0700)
committerOmar Sandoval <osandov@fb.com>
Mon, 11 Jun 2018 18:31:57 +0000 (11:31 -0700)
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 <chenr.fnst@cn.fujitsu.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
common/cpuhotplug
tests/block/008

index 6a790fe0a19c251d5cbdf38934ba199ae409a21d..70b284f7b7aa74e0d0a57421330e2e238a0950d7 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# 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"
 }
index db2a72a7e3a18c513fbcf0e70e1cd294bc616adb..4534dc3b54aa90812441510e507a1fa2a512ef52 100755 (executable)
@@ -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