FTL: Add write tests

Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: I184247316c1b85ddecc8e8b48422de606521dc36
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13323
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Kozlowski Mateusz 2022-06-13 10:43:37 +02:00 committed by Tomasz Zawadzki
parent e8c5ccf039
commit 25503b9630
7 changed files with 279 additions and 0 deletions

48
test/ftl/common.sh Normal file
View File

@ -0,0 +1,48 @@
# Common utility functions to be sourced by the libftl test scripts
function clear_lvols() {
stores=$("$rootdir/scripts/rpc.py" bdev_lvol_get_lvstores | jq -r ".[] | .uuid")
for lvs in $stores; do
"$rootdir/scripts/rpc.py" bdev_lvol_delete_lvstore -u $lvs
done
}
function create_nv_cache_bdev() {
local name=$1
local cache_bdf=$2
local base_bdev=$3
# use 5% space of base bdev
local size=$(($(get_bdev_size $base_bdev) * 5 / 100))
# Create NVMe bdev on specified device and split it so that it has the desired size
local nvc_bdev
nvc_bdev=$($rootdir/scripts/rpc.py bdev_nvme_attach_controller -b $name -t PCIe -a $cache_bdf)
local nvc_size
nvc_size=$(get_bdev_size $nvc_bdev)
if [[ $size -gt $nvc_size ]]; then
size=nvc_size
fi
$rootdir/scripts/rpc.py bdev_split_create $nvc_bdev -s $size 1
}
function create_base_bdev() {
local name=$1
local base_bdf=$2
local size=$3
# Create NVMe bdev on specified device and split it so that it has the desired size
local base_bdev
base_bdev=$($rootdir/scripts/rpc.py bdev_nvme_attach_controller -b $name -t PCIe -a $base_bdf)
local base_size
base_size=$(get_bdev_size $base_bdev)
if [[ $size -le $base_size ]]; then
$rootdir/scripts/rpc.py bdev_split_create $base_bdev -s $size 1
else
clear_lvols
lvs=$($rootdir/scripts/rpc.py bdev_lvol_create_lvstore $base_bdev lvs)
$rootdir/scripts/rpc.py bdev_lvol_create ${base_bdev}p0 $size -t -u $lvs
fi
}

View File

@ -0,0 +1,20 @@
[global]
ioengine=spdk_bdev
spdk_json_conf=${FTL_JSON_CONF}
filename=${FTL_BDEV_NAME}
thread=1
direct=1
iodepth=128
rw=randwrite
verify=crc32c
do_verify=0
verify_dump=0
verify_state_save=0
verify_fatal=1
bs=4k
random_distribution=normal
serialize_overlap=1
io_size=256M
[test]
numjobs=1

View File

@ -0,0 +1,25 @@
[global]
ioengine=spdk_bdev
spdk_json_conf=${FTL_JSON_CONF}
filename=${FTL_BDEV_NAME}
thread=1
direct=1
iodepth=128
rw=randwrite
verify=crc32c
do_verify=0
verify_dump=0
verify_state_save=0
verify_backlog=5000
verify_fatal=1
bs=4k
random_distribution=normal
serialize_overlap=1
io_size=256M
[first_half]
offset=0%
size=50%
[second_half]
offset=50%

View File

@ -0,0 +1,24 @@
[global]
ioengine=spdk_bdev
spdk_json_conf=${FTL_JSON_CONF}
filename=${FTL_BDEV_NAME}
thread=1
direct=1
iodepth=2048
size=100%
[write]
numjobs=1
rw=randwrite
verify=crc32c
do_verify=0
verify_dump=0
verify_state_save=0
verify_fatal=1
bs=512k
serialize_overlap=1
norandommap
[read]
rw=randread
bs=512k

View File

@ -0,0 +1,20 @@
[global]
ioengine=spdk_bdev
spdk_json_conf=${FTL_JSON_CONF}
filename=${FTL_BDEV_NAME}
thread=1
direct=1
iodepth=1
rw=randwrite
size=256M
verify=crc32c
do_verify=0
verify_dump=0
verify_state_save=0
verify_backlog=16
verify_fatal=1
bs=68k
random_distribution=normal
[test]
numjobs=1

67
test/ftl/fio.sh Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
testdir=$(readlink -f $(dirname $0))
rootdir=$(readlink -f $testdir/../..)
source $rootdir/test/common/autotest_common.sh
source $testdir/common.sh
declare -A suite
suite['basic']='randw-verify randw-verify-j2 randw-verify-depth128'
suite['extended']='randw-verify-qd2048-ext'
rpc_py=$rootdir/scripts/rpc.py
fio_kill() {
killprocess $svcpid
rm -f $FTL_JSON_CONF
}
device=$1
cache_device=$2
tests=${suite[$3]}
uuid=$4
timeout=240
if [[ $CONFIG_FIO_PLUGIN != y ]]; then
echo "FIO not available"
exit 1
fi
if [ -z "$tests" ]; then
echo "Invalid test suite '$2'"
exit 1
fi
export FTL_BDEV_NAME=ftl0
export FTL_JSON_CONF=$testdir/config/ftl.json
trap "fio_kill; exit 1" SIGINT SIGTERM EXIT
"$SPDK_BIN_DIR/spdk_tgt" -m 7 &
svcpid=$!
waitforlisten $svcpid
split_bdev=$(create_base_bdev nvme0 $device $((1024 * 101)))
nv_cache=$(create_nv_cache_bdev nvc0 $cache_device $split_bdev)
$rpc_py -t $timeout bdev_ftl_create -b ftl0 -d $split_bdev -c $nv_cache
waitforbdev ftl0
(
echo '{"subsystems": ['
$rpc_py save_subsystem_config -n bdev
echo ']}'
# Temporary hack so tests are always creating new instance, until clean restore is reintroduced later
) | sed 's/"uuid": "[a-f0-9\-]\{36\}"/"uuid": "00000000-0000-0000-0000-000000000000"/g' > $FTL_JSON_CONF
killprocess $svcpid
trap - SIGINT SIGTERM EXIT
for test in ${tests}; do
timing_enter $test
fio_bdev $testdir/config/fio/$test.fio
timing_exit $test
done
rm -f $FTL_JSON_CONF

75
test/ftl/ftl.sh Executable file
View File

@ -0,0 +1,75 @@
#!/usr/bin/env bash
testdir=$(readlink -f $(dirname $0))
rootdir=$(readlink -f $testdir/../..)
source $rootdir/test/common/autotest_common.sh
source $testdir/common.sh
rpc_py=$rootdir/scripts/rpc.py
function at_ftl_exit() {
killprocess "$spdk_tgt_pid"
# delete any created lvols of the base device
if [[ -n $device ]]; then
"$rootdir/build/bin/spdk_tgt" &
spdk_tgt_pid=$!
waitforlisten "$spdk_tgt_pid"
"$rpc_py" bdev_nvme_attach_controller -b nvme0 -t PCIe -a $device
clear_lvols
killprocess "$spdk_tgt_pid"
fi
# restore original driver
$rootdir/scripts/setup.sh reset
}
trap 'at_ftl_exit' SIGINT SIGTERM EXIT
# Bind device to vfio/uio driver before testing
PCI_ALLOWED="$device" PCI_BLOCKED="" DRIVER_OVERRIDE="" $rootdir/scripts/setup.sh
"$rootdir/build/bin/spdk_tgt" --wait-for-rpc &
spdk_tgt_pid=$!
waitforlisten "$spdk_tgt_pid"
$rpc_py bdev_set_options -d
$rpc_py framework_start_init
"$rpc_py" load_subsystem_config -j <($rootdir/scripts/gen_nvme.sh)
# 5GiB minimum for cache device
cache_size=$((5 * 1024 * 1024 * 1024 / 4096))
cache_disks=$("$rpc_py" bdev_get_bdevs | jq -r ".[] | select(.md_size==64 and .zoned == false and .num_blocks >= $cache_size).driver_specific.nvme[].pci_address")
for disk in $cache_disks; do
nv_cache=$disk
break
done
if [ -z "$nv_cache" ]; then
echo "Couldn't find NVMe device to be used as non-volatile cache"
exit 1
fi
# 5GiB minimum for base device (will be thin provisioned to 100GiB if necessary - it's enough for basic tests)
base_size=$((5 * 1024 * 1024 * 1024 / 4096))
base_disks=$("$rpc_py" bdev_get_bdevs | jq -r ".[] | select(.driver_specific.nvme[0].pci_address!=\"$nv_cache\" and .zoned == false and .num_blocks >= $base_size).driver_specific.nvme[].pci_address")
for disk in $base_disks; do
device=$disk
break
done
killprocess "$spdk_tgt_pid"
if [ -z "$device" ]; then
echo "Couldn't find NVMe device to be used as base device"
exit 1
fi
if [[ -z $SPDK_TEST_FTL_NIGHTLY ]]; then
run_test "ftl_fio_basic" $testdir/fio.sh $device $nv_cache basic
fi
if [ $SPDK_TEST_FTL_EXTENDED -eq 1 ]; then
run_test "ftl_fio_extended" $testdir/fio.sh $device $nv_cache extended
fi