Spdk/test/ublk/ublk.sh
Jim Harris ee31bc9d19 test/ublk: add parameter for num devices
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>
2023-01-25 10:52:36 +00:00

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