test/ublk/ublk.sh 256 will now create 256 ublk devices, to try to test the ctrlr_cmd queueing logic when the ctrl uring runs out of sqes. It's actually difficult to induce the condition, since the kernel SQPOLL thread can usually keep up with the SPDK process submitting the control commands. The best way to induce it is by *not* stopping the disks at the end of a test with a lot of disks, and letting ublk_destroy_target stop all of them at once. Even then, with the ublk logging enabled, even that extra delay for each commands opcode is enough to help the SQPOLL thread to keep up. Commenting out the first UBLK_DEBUGLOG in ublk_ctrl_cmd() does help it run out of sqes, at least in my setup. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I8f7a6ca29fd69613d44a89adc7e60563b274d155 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16458 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
114 lines
3.4 KiB
Bash
Executable File
114 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
# Copyright (C) 2022 Intel Corporation.
|
|
# All rights reserved.
|
|
#
|
|
testdir=$(readlink -f "$(dirname $0)")
|
|
rootdir=$(readlink -f "$testdir/../..")
|
|
source "$rootdir/test/common/autotest_common.sh"
|
|
source "$rootdir/test/lvol/common.sh"
|
|
|
|
if [[ -z $1 ]]; then
|
|
NUM_DEVS=4
|
|
NUM_QUEUE=4
|
|
QUEUE_DEPTH=512
|
|
MALLOC_SIZE_MB=128
|
|
# issue ublk_stop_disk cmds before ublk_destroy_target
|
|
STOP_DISKS=1
|
|
else
|
|
# Use smaller parameters when user specifies the number
|
|
# of devices, to guard against memory exhaustion.
|
|
NUM_DEVS=$1
|
|
NUM_QUEUE=1
|
|
QUEUE_DEPTH=16
|
|
MALLOC_SIZE_MB=2
|
|
fi
|
|
|
|
MALLOC_BS=4096
|
|
FILE_SIZE=$((MALLOC_SIZE_MB * 1024 * 1024))
|
|
MAX_DEV_ID=$((NUM_DEVS - 1))
|
|
|
|
function test_create_ublk() {
|
|
# create a ublk target
|
|
ublk_target=$(rpc_cmd ublk_create_target)
|
|
# create a malloc bdev
|
|
malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
|
|
# Add ublk device
|
|
ublk_id=$(rpc_cmd ublk_start_disk $malloc_name 0 -q $NUM_QUEUE -d $QUEUE_DEPTH)
|
|
ublk_path="/dev/ublkb$ublk_id"
|
|
ublk_dev=$(rpc_cmd ublk_get_disks -n $ublk_id)
|
|
# verify its parameters
|
|
[[ "$(jq -r '.[0].ublk_device' <<< "$ublk_dev")" = "$ublk_path" ]]
|
|
[[ "$(jq -r '.[0].id' <<< "$ublk_dev")" = "$ublk_id" ]]
|
|
[[ "$(jq -r '.[0].queue_depth' <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]]
|
|
[[ "$(jq -r '.[0].num_queues' <<< "$ublk_dev")" = "$NUM_QUEUE" ]]
|
|
[[ "$(jq -r '.[0].bdev_name' <<< "$ublk_dev")" = "$malloc_name" ]]
|
|
|
|
# Run fio in background that writes to ublk
|
|
run_fio_test /dev/ublkb0 0 $FILE_SIZE "write" "0xcc" "--time_based --runtime=10"
|
|
|
|
# clean up
|
|
rpc_cmd ublk_stop_disk "$ublk_id"
|
|
# make sure we can't delete the same ublk
|
|
NOT rpc_cmd ublk_stop_disk "$ublk_id"
|
|
rpc_cmd ublk_destroy_target
|
|
|
|
rpc_cmd bdev_malloc_delete "$malloc_name"
|
|
check_leftover_devices
|
|
}
|
|
|
|
function test_create_multi_ublk() {
|
|
# create a ublk target
|
|
ublk_target=$(rpc_cmd ublk_create_target)
|
|
|
|
for i in $(seq 0 $MAX_DEV_ID); do
|
|
# create a malloc bdev
|
|
malloc_name=$(rpc_cmd bdev_malloc_create -b "Malloc${i}" $MALLOC_SIZE_MB $MALLOC_BS)
|
|
# add ublk device
|
|
ublk_id=$(rpc_cmd ublk_start_disk $malloc_name "${i}" -q $NUM_QUEUE -d $QUEUE_DEPTH)
|
|
done
|
|
|
|
ublk_dev=$(rpc_cmd ublk_get_disks)
|
|
for i in $(seq 0 $MAX_DEV_ID); do
|
|
# verify its parameters
|
|
[[ "$(jq -r ".[${i}].ublk_device" <<< "$ublk_dev")" = "/dev/ublkb${i}" ]]
|
|
[[ "$(jq -r ".[${i}].id" <<< "$ublk_dev")" = "${i}" ]]
|
|
[[ "$(jq -r ".[${i}].queue_depth" <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]]
|
|
[[ "$(jq -r ".[${i}].num_queues" <<< "$ublk_dev")" = "$NUM_QUEUE" ]]
|
|
[[ "$(jq -r ".[${i}].bdev_name" <<< "$ublk_dev")" = "Malloc${i}" ]]
|
|
done
|
|
|
|
# To help test the ctrl cmd queuing logic, we omit the ublk_stop_disk
|
|
# RPCs. Then the ublk_destroy_target RPC will stop all of the disks
|
|
# in very quick succession which exhausts the control io_uring SQEs
|
|
if [[ "$STOP_DISKS" = "1" ]]; then
|
|
for i in $(seq 0 $MAX_DEV_ID); do
|
|
rpc_cmd ublk_stop_disk "${i}"
|
|
done
|
|
fi
|
|
|
|
# Shutting down a lot of disks can take a long time, so extend the RPC timeout
|
|
"$rootdir/scripts/rpc.py" -t 120 ublk_destroy_target
|
|
|
|
for i in $(seq 0 $MAX_DEV_ID); do
|
|
rpc_cmd bdev_malloc_delete "Malloc${i}"
|
|
done
|
|
check_leftover_devices
|
|
}
|
|
|
|
function cleanup() {
|
|
killprocess $spdk_pid
|
|
}
|
|
|
|
modprobe ublk_drv
|
|
"$SPDK_BIN_DIR/spdk_tgt" -m 0x3 -L ublk &
|
|
spdk_pid=$!
|
|
trap 'cleanup; exit 1' SIGINT SIGTERM EXIT
|
|
waitforlisten $spdk_pid
|
|
|
|
run_test "test_create_ublk" test_create_ublk
|
|
run_test "test_create_multi_ublk" test_create_multi_ublk
|
|
|
|
trap - SIGINT SIGTERM EXIT
|
|
cleanup
|