xref: /spdk/test/iscsi_tgt/qos/qos.sh (revision eb53c23236cccb6b698b7ca70ee783da1c574b5f)
11559a7cdSchenlo2x#!/usr/bin/env bash
2*eb53c232Spaul luse#  SPDX-License-Identifier: BSD-3-Clause
3*eb53c232Spaul luse#  Copyright (C) 2018 Intel Corporation
4*eb53c232Spaul luse#  All rights reserved.
5*eb53c232Spaul luse#
61559a7cdSchenlo2xtestdir=$(readlink -f $(dirname $0))
71559a7cdSchenlo2xrootdir=$(readlink -f $testdir/../../..)
81559a7cdSchenlo2xsource $rootdir/test/common/autotest_common.sh
91559a7cdSchenlo2xsource $rootdir/test/iscsi_tgt/common.sh
101559a7cdSchenlo2x
1199dd44e8STomasz Zawadzkiiscsitestinit
1203b9841dSSeth Howell
13a1e4e727SDarek Stojaczykfunction run_fio() {
14a1e4e727SDarek Stojaczyk	local bdev_name=$1
15074df1d8SPawel Kaminski	local iostats
16074df1d8SPawel Kaminski	local start_io_count
17074df1d8SPawel Kaminski	local start_bytes_read
18074df1d8SPawel Kaminski	local end_io_count
19074df1d8SPawel Kaminski	local end_bytes_read
20a1e4e727SDarek Stojaczyk	local run_time=5
21406a315eSJim Harris
22074df1d8SPawel Kaminski	iostats=$($rpc_py bdev_get_iostat -b $bdev_name)
23074df1d8SPawel Kaminski	start_io_count=$(jq -r '.bdevs[0].num_read_ops' <<< "$iostats")
24074df1d8SPawel Kaminski	start_bytes_read=$(jq -r '.bdevs[0].bytes_read' <<< "$iostats")
257b00091aSLiang Yan
265470a058SSeth Howell	$fio_py -p iscsi -i 1024 -d 128 -t randread -r $run_time
277b00091aSLiang Yan
28326e68fcSMaciej Wawryk	iostats=$($rpc_py bdev_get_iostat -b $bdev_name)
29074df1d8SPawel Kaminski	end_io_count=$(jq -r '.bdevs[0].num_read_ops' <<< "$iostats")
30074df1d8SPawel Kaminski	end_bytes_read=$(jq -r '.bdevs[0].bytes_read' <<< "$iostats")
317b00091aSLiang Yan
329a4a87b5SMaciej Wawryk	IOPS_RESULT=$(((end_io_count - start_io_count) / run_time))
339a4a87b5SMaciej Wawryk	BANDWIDTH_RESULT=$(((end_bytes_read - start_bytes_read) / run_time))
34a1e4e727SDarek Stojaczyk}
3522364ca8SDarek Stojaczyk
36a1e4e727SDarek Stojaczykfunction verify_qos_limits() {
37a1e4e727SDarek Stojaczyk	local result=$1
38a1e4e727SDarek Stojaczyk	local limit=$2
39b30a59d6SJim Harris
40844c8ec3SMichal Berger	[ "$(bc <<< "$result > $limit*0.85")" -eq 1 ] \
41844c8ec3SMichal Berger		&& [ "$(bc <<< "$result < $limit*1.05")" -eq 1 ]
421559a7cdSchenlo2x}
431559a7cdSchenlo2x
441559a7cdSchenlo2xif [ -z "$TARGET_IP" ]; then
451559a7cdSchenlo2x	echo "TARGET_IP not defined in environment"
461559a7cdSchenlo2x	exit 1
471559a7cdSchenlo2xfi
481559a7cdSchenlo2x
491559a7cdSchenlo2xif [ -z "$INITIATOR_IP" ]; then
501559a7cdSchenlo2x	echo "INITIATOR_IP not defined in environment"
511559a7cdSchenlo2x	exit 1
521559a7cdSchenlo2xfi
531559a7cdSchenlo2x
541559a7cdSchenlo2xMALLOC_BDEV_SIZE=64
555595a7caSJim HarrisMALLOC_BLOCK_SIZE=512
5622364ca8SDarek StojaczykIOPS_RESULT=
5722364ca8SDarek StojaczykBANDWIDTH_RESULT=
5819f0c9a0SMichal Bergerfio_py="$rootdir/scripts/fio-wrapper"
591559a7cdSchenlo2x
601559a7cdSchenlo2xtiming_enter start_iscsi_tgt
611559a7cdSchenlo2x
62b4c5509cSMichal Berger"${ISCSI_APP[@]}" &
631559a7cdSchenlo2xpid=$!
641559a7cdSchenlo2xecho "Process pid: $pid"
6599dd44e8STomasz Zawadzkitrap 'killprocess $pid; iscsitestfini; exit 1' SIGINT SIGTERM EXIT
661559a7cdSchenlo2xwaitforlisten $pid
671559a7cdSchenlo2xecho "iscsi_tgt is listening. Running tests..."
681559a7cdSchenlo2x
691559a7cdSchenlo2xtiming_exit start_iscsi_tgt
701559a7cdSchenlo2x
710f4b3490SPawel Kaminski$rpc_py iscsi_create_portal_group $PORTAL_TAG $TARGET_IP:$ISCSI_PORT
7294dd4b9aSPawel Kaminski$rpc_py iscsi_create_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK
737964f1dfSPawel Kaminski$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE
741559a7cdSchenlo2x# "Malloc0:0" ==> use Malloc0 blockdev for LUN0
751559a7cdSchenlo2x# "1:2" ==> map PortalGroup1 to InitiatorGroup2
761559a7cdSchenlo2x# "64" ==> iSCSI queue depth 64
771559a7cdSchenlo2x# "-d" ==> disable CHAP authentication
78758b2f94SPawel Kaminski$rpc_py iscsi_create_target_node Target1 Target1_alias 'Malloc0:0' $PORTAL_TAG:$INITIATOR_TAG 64 -d
791559a7cdSchenlo2xsleep 1
801559a7cdSchenlo2x
811559a7cdSchenlo2xiscsiadm -m discovery -t sendtargets -p $TARGET_IP:$ISCSI_PORT
821559a7cdSchenlo2xiscsiadm -m node --login -p $TARGET_IP:$ISCSI_PORT
831559a7cdSchenlo2x
8499dd44e8STomasz Zawadzkitrap 'iscsicleanup; killprocess $pid; iscsitestfini; exit 1' SIGINT SIGTERM EXIT
851559a7cdSchenlo2x
8622364ca8SDarek Stojaczyk# Run FIO without any QOS limits to determine the raw performance
87a1e4e727SDarek Stojaczykrun_fio Malloc0
88092360ceSGangCao
8922364ca8SDarek Stojaczyk# Set IOPS/bandwidth limit to 50% of the actual unrestrained performance.
909a4a87b5SMaciej WawrykIOPS_LIMIT=$((IOPS_RESULT / 2))
919a4a87b5SMaciej WawrykBANDWIDTH_LIMIT=$((BANDWIDTH_RESULT / 2))
9222364ca8SDarek Stojaczyk# Set READ bandwidth limit to 50% of the RW bandwidth limit to be able
9322364ca8SDarek Stojaczyk# to differentiate those two.
949a4a87b5SMaciej WawrykREAD_BANDWIDTH_LIMIT=$((BANDWIDTH_LIMIT / 2))
9522364ca8SDarek Stojaczyk
9622364ca8SDarek Stojaczyk# Also round them down to nearest multiple of either 1000 IOPS or 1MB BW
9722364ca8SDarek Stojaczyk# which are the minimal QoS granularities
989a4a87b5SMaciej WawrykIOPS_LIMIT=$((IOPS_LIMIT / 1000 * 1000))
999a4a87b5SMaciej WawrykBANDWIDTH_LIMIT_MB=$((BANDWIDTH_LIMIT / 1024 / 1024))
1009a4a87b5SMaciej WawrykBANDWIDTH_LIMIT=$((BANDWIDTH_LIMIT_MB * 1024 * 1024))
1019a4a87b5SMaciej WawrykREAD_BANDWIDTH_LIMIT_MB=$((READ_BANDWIDTH_LIMIT / 1024 / 1024))
1029a4a87b5SMaciej WawrykREAD_BANDWIDTH_LIMIT=$((READ_BANDWIDTH_LIMIT_MB * 1024 * 1024))
10322364ca8SDarek Stojaczyk
1041559a7cdSchenlo2x# Limit the I/O rate by RPC, then confirm the observed rate matches.
105c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_ios_per_sec $IOPS_LIMIT
106a1e4e727SDarek Stojaczykrun_fio Malloc0
107a1e4e727SDarek Stojaczykverify_qos_limits $IOPS_RESULT $IOPS_LIMIT
1081559a7cdSchenlo2x
1091559a7cdSchenlo2x# Now disable the rate limiting, and confirm the observed rate is not limited anymore.
110c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_ios_per_sec 0
111a1e4e727SDarek Stojaczykrun_fio Malloc0
112a1e4e727SDarek Stojaczyk[ "$IOPS_RESULT" -gt "$IOPS_LIMIT" ]
1131559a7cdSchenlo2x
1141559a7cdSchenlo2x# Limit the I/O rate again.
115c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_ios_per_sec $IOPS_LIMIT
116a1e4e727SDarek Stojaczykrun_fio Malloc0
117a1e4e727SDarek Stojaczykverify_qos_limits $IOPS_RESULT $IOPS_LIMIT
118a1e4e727SDarek Stojaczyk
1191559a7cdSchenlo2xecho "I/O rate limiting tests successful"
1201559a7cdSchenlo2x
1217b00091aSLiang Yan# Limit the I/O bandwidth rate by RPC, then confirm the observed rate matches.
122c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_ios_per_sec 0 --rw_mbytes_per_sec $BANDWIDTH_LIMIT_MB
123a1e4e727SDarek Stojaczykrun_fio Malloc0
124a1e4e727SDarek Stojaczykverify_qos_limits $BANDWIDTH_RESULT $BANDWIDTH_LIMIT
1257b00091aSLiang Yan
1267b00091aSLiang Yan# Now disable the bandwidth rate limiting, and confirm the observed rate is not limited anymore.
127c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_mbytes_per_sec 0
128a1e4e727SDarek Stojaczykrun_fio Malloc0
129a1e4e727SDarek Stojaczyk[ "$BANDWIDTH_RESULT" -gt "$BANDWIDTH_LIMIT" ]
1307b00091aSLiang Yan
13105b43152SGangCao# Limit the I/O bandwidth rate again with both read/write and read/only.
132c61e14beSMaciej Wawryk$rpc_py bdev_set_qos_limit Malloc0 --rw_mbytes_per_sec $BANDWIDTH_LIMIT_MB --r_mbytes_per_sec $READ_BANDWIDTH_LIMIT_MB
133a1e4e727SDarek Stojaczykrun_fio Malloc0
134a1e4e727SDarek Stojaczykverify_qos_limits $BANDWIDTH_RESULT $READ_BANDWIDTH_LIMIT
135a1e4e727SDarek Stojaczyk
1367b00091aSLiang Yanecho "I/O bandwidth limiting tests successful"
1377b00091aSLiang Yan
1381559a7cdSchenlo2xiscsicleanup
139a5a296dcSPawel Kaminski$rpc_py iscsi_delete_target_node 'iqn.2016-06.io.spdk:Target1'
1401559a7cdSchenlo2x
1411559a7cdSchenlo2xrm -f ./local-job0-0-verify.state
1421559a7cdSchenlo2xtrap - SIGINT SIGTERM EXIT
1431559a7cdSchenlo2xkillprocess $pid
1441559a7cdSchenlo2x
14599dd44e8STomasz Zawadzkiiscsitestfini
146