xref: /aosp_15_r20/external/ublksrv/tests/common/fio_common (revision 94c4a1e103eb1715230460aab379dff275992c20)
1*94c4a1e1SFrank Piva#!/bin/bash
2*94c4a1e1SFrank Piva# SPDX-License-Identifier: MIT or GPL-2.0-only
3*94c4a1e1SFrank Piva
4*94c4a1e1SFrank Pivadeclare -A TEST_RUN
5*94c4a1e1SFrank Piva
6*94c4a1e1SFrank Pivadeclare -A FIO_TERSE_FIELDS
7*94c4a1e1SFrank PivaFIO_TERSE_FIELDS=(
8*94c4a1e1SFrank Piva	# Read status
9*94c4a1e1SFrank Piva	["read io"]=6
10*94c4a1e1SFrank Piva	["read bandwidth"]=7
11*94c4a1e1SFrank Piva	["read iops"]=8
12*94c4a1e1SFrank Piva	["read runtime"]=9
13*94c4a1e1SFrank Piva	["read slat min"]=10
14*94c4a1e1SFrank Piva	["read slat max"]=11
15*94c4a1e1SFrank Piva	["read slat mean"]=12
16*94c4a1e1SFrank Piva	["read slat stdev"]=13
17*94c4a1e1SFrank Piva	["read clat min"]=14
18*94c4a1e1SFrank Piva	["read clat max"]=15
19*94c4a1e1SFrank Piva	["read clat mean"]=16
20*94c4a1e1SFrank Piva	["read clat stdev"]=17
21*94c4a1e1SFrank Piva	# read clat percentiles are 18-37
22*94c4a1e1SFrank Piva	["read lat min"]=38
23*94c4a1e1SFrank Piva	["read lat max"]=39
24*94c4a1e1SFrank Piva	["read lat mean"]=40
25*94c4a1e1SFrank Piva	["read lat stdev"]=41
26*94c4a1e1SFrank Piva	["read bandwidth min"]=42
27*94c4a1e1SFrank Piva	["read bandwidth max"]=43
28*94c4a1e1SFrank Piva	["read bandwidth %"]=44
29*94c4a1e1SFrank Piva	["read bandwidth mean"]=45
30*94c4a1e1SFrank Piva	["read bandwidth stdev"]=46
31*94c4a1e1SFrank Piva
32*94c4a1e1SFrank Piva	# Write status
33*94c4a1e1SFrank Piva	["write io"]=47
34*94c4a1e1SFrank Piva	["write bandwidth"]=48
35*94c4a1e1SFrank Piva	["write iops"]=49
36*94c4a1e1SFrank Piva	["write runtime"]=50
37*94c4a1e1SFrank Piva	["write slat min"]=51
38*94c4a1e1SFrank Piva	["write slat max"]=52
39*94c4a1e1SFrank Piva	["write slat mean"]=53
40*94c4a1e1SFrank Piva	["write slat stdev"]=54
41*94c4a1e1SFrank Piva	["write clat min"]=55
42*94c4a1e1SFrank Piva	["write clat max"]=56
43*94c4a1e1SFrank Piva	["write clat mean"]=57
44*94c4a1e1SFrank Piva	["write clat stdev"]=58
45*94c4a1e1SFrank Piva	# write clat percentiles are 59-78
46*94c4a1e1SFrank Piva	["write lat min"]=79
47*94c4a1e1SFrank Piva	["write lat max"]=80
48*94c4a1e1SFrank Piva	["write lat mean"]=81
49*94c4a1e1SFrank Piva	["write lat stdev"]=82
50*94c4a1e1SFrank Piva	["write bandwidth min"]=83
51*94c4a1e1SFrank Piva	["write bandwidth max"]=84
52*94c4a1e1SFrank Piva	["write bandwidth %"]=85
53*94c4a1e1SFrank Piva	["write bandwidth mean"]=86
54*94c4a1e1SFrank Piva	["write bandwidth stdev"]=87
55*94c4a1e1SFrank Piva
56*94c4a1e1SFrank Piva	# Trim status
57*94c4a1e1SFrank Piva	["trim io"]=88
58*94c4a1e1SFrank Piva	["trim bandwidth"]=89
59*94c4a1e1SFrank Piva	["trim iops"]=90
60*94c4a1e1SFrank Piva	["trim runtime"]=91
61*94c4a1e1SFrank Piva	["trim slat min"]=92
62*94c4a1e1SFrank Piva	["trim slat max"]=93
63*94c4a1e1SFrank Piva	["trim slat mean"]=94
64*94c4a1e1SFrank Piva	["trim slat stdev"]=95
65*94c4a1e1SFrank Piva	["trim clat min"]=96
66*94c4a1e1SFrank Piva	["trim clat max"]=97
67*94c4a1e1SFrank Piva	["trim clat mean"]=98
68*94c4a1e1SFrank Piva	["trim clat stdev"]=99
69*94c4a1e1SFrank Piva	# trim clat percentiles are 100-119
70*94c4a1e1SFrank Piva	["trim lat min"]=120
71*94c4a1e1SFrank Piva	["trim lat max"]=121
72*94c4a1e1SFrank Piva	["trim lat mean"]=122
73*94c4a1e1SFrank Piva	["trim lat stdev"]=123
74*94c4a1e1SFrank Piva	["trim bandwidth min"]=124
75*94c4a1e1SFrank Piva	["trim bandwidth max"]=125
76*94c4a1e1SFrank Piva	["trim bandwidth %"]=126
77*94c4a1e1SFrank Piva	["trim bandwidth mean"]=127
78*94c4a1e1SFrank Piva	["trim bandwidth stdev"]=128
79*94c4a1e1SFrank Piva
80*94c4a1e1SFrank Piva	# CPU usage
81*94c4a1e1SFrank Piva	["user cpu"]=129
82*94c4a1e1SFrank Piva	["system cpu"]=130
83*94c4a1e1SFrank Piva	["context switches"]=131
84*94c4a1e1SFrank Piva	["major page faults"]=132
85*94c4a1e1SFrank Piva	["minor page faults"]=133
86*94c4a1e1SFrank Piva
87*94c4a1e1SFrank Piva	# IO depth distribution
88*94c4a1e1SFrank Piva	["io depth <=1"]=134
89*94c4a1e1SFrank Piva	["io depth 2"]=135
90*94c4a1e1SFrank Piva	["io depth 4"]=136
91*94c4a1e1SFrank Piva	["io depth 8"]=137
92*94c4a1e1SFrank Piva	["io depth 16"]=138
93*94c4a1e1SFrank Piva	["io depth 32"]=139
94*94c4a1e1SFrank Piva	["io depth >=64"]=140
95*94c4a1e1SFrank Piva
96*94c4a1e1SFrank Piva	# IO latency distribution
97*94c4a1e1SFrank Piva	["io latency <=2 us"]=141
98*94c4a1e1SFrank Piva	["io latency 4 us"]=142
99*94c4a1e1SFrank Piva	["io latency 10 us"]=143
100*94c4a1e1SFrank Piva	["io latency 20 us"]=144
101*94c4a1e1SFrank Piva	["io latency 50 us"]=145
102*94c4a1e1SFrank Piva	["io latency 100 us"]=146
103*94c4a1e1SFrank Piva	["io latency 250 us"]=147
104*94c4a1e1SFrank Piva	["io latency 500 us"]=148
105*94c4a1e1SFrank Piva	["io latency 750 us"]=149
106*94c4a1e1SFrank Piva	["io latency 1000 us"]=150
107*94c4a1e1SFrank Piva	["io latency <=2 ms"]=151
108*94c4a1e1SFrank Piva	["io latency 4 ms"]=152
109*94c4a1e1SFrank Piva	["io latency 10 ms"]=153
110*94c4a1e1SFrank Piva	["io latency 20 ms"]=154
111*94c4a1e1SFrank Piva	["io latency 50 ms"]=155
112*94c4a1e1SFrank Piva	["io latency 100 ms"]=156
113*94c4a1e1SFrank Piva	["io latency 250 ms"]=157
114*94c4a1e1SFrank Piva	["io latency 500 ms"]=158
115*94c4a1e1SFrank Piva	["io latency 750 ms"]=159
116*94c4a1e1SFrank Piva	["io latency 1000 ms"]=160
117*94c4a1e1SFrank Piva	["io latency 2000 ms"]=161
118*94c4a1e1SFrank Piva	["io latency >=2000 ms"]=162
119*94c4a1e1SFrank Piva
120*94c4a1e1SFrank Piva	# Disk utilization (11 fields per disk)
121*94c4a1e1SFrank Piva)
122*94c4a1e1SFrank Piva
123*94c4a1e1SFrank PivaFIO_OUTPUT="$TEST_DIR/.fio_perf"
124*94c4a1e1SFrank Piva
125*94c4a1e1SFrank Piva_fio_perf_report() {
126*94c4a1e1SFrank Piva	# If there is more than one group, we don't know what to report.
127*94c4a1e1SFrank Piva	if [[ $(wc -l < "$FIO_OUTPUT") -gt 1 ]]; then
128*94c4a1e1SFrank Piva		echo "_fio_perf: too many terse lines" >&2
129*94c4a1e1SFrank Piva		return
130*94c4a1e1SFrank Piva	fi
131*94c4a1e1SFrank Piva
132*94c4a1e1SFrank Piva	local name field value
133*94c4a1e1SFrank Piva	for name in "${FIO_PERF_FIELDS[@]}"; do
134*94c4a1e1SFrank Piva		field="${FIO_TERSE_FIELDS["$name"]}"
135*94c4a1e1SFrank Piva		if [[ -z $field ]]; then
136*94c4a1e1SFrank Piva			echo "_fio_perf: unknown fio terse field '$name'" >&2
137*94c4a1e1SFrank Piva			continue
138*94c4a1e1SFrank Piva		fi
139*94c4a1e1SFrank Piva		value="$(cut -d ';' -f "$field" "$FIO_OUTPUT")"
140*94c4a1e1SFrank Piva		TEST_RUN["$FIO_PERF_PREFIX$name"]="$value"
141*94c4a1e1SFrank Piva	done
142*94c4a1e1SFrank Piva}
143*94c4a1e1SFrank Piva
144*94c4a1e1SFrank Piva__run_fio_libaio() {
145*94c4a1e1SFrank Piva	DEVS=$1
146*94c4a1e1SFrank Piva	BS=$2
147*94c4a1e1SFrank Piva	RW=$3
148*94c4a1e1SFrank Piva	JOBS=$4
149*94c4a1e1SFrank Piva	RTIME=$5
150*94c4a1e1SFrank Piva
151*94c4a1e1SFrank Piva	QD=128
152*94c4a1e1SFrank Piva	BATCH=16
153*94c4a1e1SFrank Piva	FIO=fio
154*94c4a1e1SFrank Piva
155*94c4a1e1SFrank Piva	$FIO --output=$FIO_OUTPUT --output-format=terse --terse-version=4 --group_reporting=1 \
156*94c4a1e1SFrank Piva		--bs=$BS --ioengine=libaio \
157*94c4a1e1SFrank Piva        --iodepth=$QD \
158*94c4a1e1SFrank Piva        --iodepth_batch_submit=$BATCH \
159*94c4a1e1SFrank Piva        --iodepth_batch_complete_min=$BATCH \
160*94c4a1e1SFrank Piva        --filename=$DEVS --gtod_reduce=1 \
161*94c4a1e1SFrank Piva        --direct=1 --runtime=$RTIME --numjobs=$JOBS --rw=$RW \
162*94c4a1e1SFrank Piva        --name=test > /dev/null 2>&1
163*94c4a1e1SFrank Piva}
164*94c4a1e1SFrank Piva
165*94c4a1e1SFrank Piva__ublk_loop_backing_file() {
166*94c4a1e1SFrank Piva	eval $UBLK list > ${UBLK_TMP}
167*94c4a1e1SFrank Piva	file=`cat ${UBLK_TMP} | grep "loop" | awk '{print $2}' | awk -F "," '{print $1}' | awk -F ":" '{print $2}'`
168*94c4a1e1SFrank Piva	echo $file | xargs
169*94c4a1e1SFrank Piva}
170*94c4a1e1SFrank Piva
171*94c4a1e1SFrank Piva__ublk_dev_id() {
172*94c4a1e1SFrank Piva	local dev=$1
173*94c4a1e1SFrank Piva	dev_id=`echo "$dev" | awk '{print substr($1, 11)}'`
174*94c4a1e1SFrank Piva	echo "$dev_id"
175*94c4a1e1SFrank Piva}
176*94c4a1e1SFrank Piva
177*94c4a1e1SFrank Piva__ublk_get_pid() {
178*94c4a1e1SFrank Piva	local dev=$1
179*94c4a1e1SFrank Piva	local dev_id=`__ublk_dev_id $dev`
180*94c4a1e1SFrank Piva
181*94c4a1e1SFrank Piva	eval $UBLK list -n $dev_id > ${UBLK_TMP}
182*94c4a1e1SFrank Piva	pid=`cat ${UBLK_TMP} | grep "pid" | awk '{print $7}'`
183*94c4a1e1SFrank Piva	echo $pid
184*94c4a1e1SFrank Piva}
185*94c4a1e1SFrank Piva
186*94c4a1e1SFrank Piva__ublk_get_queue_tid() {
187*94c4a1e1SFrank Piva	local dev=$1
188*94c4a1e1SFrank Piva	local qid=$2
189*94c4a1e1SFrank Piva	local dev_id=`__ublk_dev_id $dev`
190*94c4a1e1SFrank Piva
191*94c4a1e1SFrank Piva	eval $UBLK list -n ${dev_id} > ${UBLK_TMP}
192*94c4a1e1SFrank Piva	q_tid=`cat ${UBLK_TMP} | grep "queue ${qid}" | awk '{print $4}'`
193*94c4a1e1SFrank Piva	echo $q_tid
194*94c4a1e1SFrank Piva}
195*94c4a1e1SFrank Piva
196*94c4a1e1SFrank Piva__ublk_get_dev_state() {
197*94c4a1e1SFrank Piva	local dev=$1
198*94c4a1e1SFrank Piva	local dev_id=`__ublk_dev_id $dev`
199*94c4a1e1SFrank Piva
200*94c4a1e1SFrank Piva	eval $UBLK list -n ${dev_id} > ${UBLK_TMP}
201*94c4a1e1SFrank Piva	state=`cat ${UBLK_TMP} | grep "state" | awk '{print $11}'`
202*94c4a1e1SFrank Piva	echo $state
203*94c4a1e1SFrank Piva}
204*94c4a1e1SFrank Piva
205*94c4a1e1SFrank Piva__run_fio_perf() {
206*94c4a1e1SFrank Piva	__run_fio_libaio $@
207*94c4a1e1SFrank Piva	_fio_perf_report
208*94c4a1e1SFrank Piva}
209*94c4a1e1SFrank Piva
210*94c4a1e1SFrank Piva__remove_ublk_dev_return() {
211*94c4a1e1SFrank Piva	local dev="$1"
212*94c4a1e1SFrank Piva	if [ "$dev" == "*" ]; then
213*94c4a1e1SFrank Piva		eval $UBLK del -a
214*94c4a1e1SFrank Piva	else
215*94c4a1e1SFrank Piva		dev_id=`__ublk_dev_id $dev`
216*94c4a1e1SFrank Piva		eval $UBLK del -n "$dev_id"
217*94c4a1e1SFrank Piva	fi
218*94c4a1e1SFrank Piva	RES=$?
219*94c4a1e1SFrank Piva	udevadm settle
220*94c4a1e1SFrank Piva	echo $RES
221*94c4a1e1SFrank Piva}
222*94c4a1e1SFrank Piva
223*94c4a1e1SFrank Piva__remove_ublk_dev() {
224*94c4a1e1SFrank Piva	__remove_ublk_dev_return $@ > /dev/null 2>&1
225*94c4a1e1SFrank Piva}
226*94c4a1e1SFrank Piva
227*94c4a1e1SFrank Piva__find_free_ublk_id()
228*94c4a1e1SFrank Piva{
229*94c4a1e1SFrank Piva	for id in `seq 0 64`; do
230*94c4a1e1SFrank Piva		[ -c /dev/ublkc${id} ] && continue
231*94c4a1e1SFrank Piva		echo $id
232*94c4a1e1SFrank Piva		break
233*94c4a1e1SFrank Piva	done
234*94c4a1e1SFrank Piva	[ $id == "64" ] && echo "-"
235*94c4a1e1SFrank Piva}
236*94c4a1e1SFrank Piva
237*94c4a1e1SFrank Piva__create_ublk_dev()
238*94c4a1e1SFrank Piva{
239*94c4a1e1SFrank Piva	id=`__find_free_ublk_id`
240*94c4a1e1SFrank Piva	[ ${id} == "-" ] && echo "no free ublk device nodes" && exit -1
241*94c4a1e1SFrank Piva	eval $UBLK add ${T_TYPE_PARAMS} -n $id > /dev/null 2>&1
242*94c4a1e1SFrank Piva	udevadm settle
243*94c4a1e1SFrank Piva	echo "/dev/ublkb${id}"
244*94c4a1e1SFrank Piva}
245*94c4a1e1SFrank Piva
246*94c4a1e1SFrank Piva__recover_ublk_dev()
247*94c4a1e1SFrank Piva{
248*94c4a1e1SFrank Piva	local dev=$1
249*94c4a1e1SFrank Piva	local dev_id=`__ublk_dev_id $dev`
250*94c4a1e1SFrank Piva
251*94c4a1e1SFrank Piva	eval $UBLK recover -n $dev_id
252*94c4a1e1SFrank Piva	RES=$?
253*94c4a1e1SFrank Piva	echo $RES
254*94c4a1e1SFrank Piva}
255*94c4a1e1SFrank Piva
256*94c4a1e1SFrank Piva__get_cpu_utils()
257*94c4a1e1SFrank Piva{
258*94c4a1e1SFrank Piva	local user_cpu=`echo ${TEST_RUN["user cpu"]} | awk -F "." '{print $1}'`
259*94c4a1e1SFrank Piva	local sys_cpu=`echo ${TEST_RUN["system cpu"]} | awk -F "." '{print $1}'`
260*94c4a1e1SFrank Piva	echo "cpu_util(${user_cpu}% ${sys_cpu}%)"
261*94c4a1e1SFrank Piva}
262*94c4a1e1SFrank Piva
263*94c4a1e1SFrank Piva__run_dev_perf_no_create()
264*94c4a1e1SFrank Piva{
265*94c4a1e1SFrank Piva	local TYPE=$1
266*94c4a1e1SFrank Piva	local JOBS=$2
267*94c4a1e1SFrank Piva	local DEV=$3
268*94c4a1e1SFrank Piva	local RT=$TRUNTIME
269*94c4a1e1SFrank Piva	local BS=4k
270*94c4a1e1SFrank Piva	local FIO_PERF_FIELDS=("read iops" "write iops" "user cpu" "system cpu")
271*94c4a1e1SFrank Piva
272*94c4a1e1SFrank Piva	RW="randwrite"
273*94c4a1e1SFrank Piva	__run_fio_perf $DEV $BS $RW $JOBS 20
274*94c4a1e1SFrank Piva	cpu_util=`__get_cpu_utils`
275*94c4a1e1SFrank Piva	echo -e "\t$RW($BS): jobs $JOBS, iops ${TEST_RUN["write iops"]}, $cpu_util"
276*94c4a1e1SFrank Piva
277*94c4a1e1SFrank Piva	RW="randread"
278*94c4a1e1SFrank Piva	__run_fio_perf $DEV $BS $RW $JOBS $RT
279*94c4a1e1SFrank Piva	cpu_util=`__get_cpu_utils`
280*94c4a1e1SFrank Piva	echo -e "\t$RW($BS): jobs $JOBS, iops ${TEST_RUN["read iops"]}, $cpu_util"
281*94c4a1e1SFrank Piva
282*94c4a1e1SFrank Piva	RW="randrw"
283*94c4a1e1SFrank Piva	__run_fio_perf $DEV $BS $RW $JOBS $RT
284*94c4a1e1SFrank Piva	cpu_util=`__get_cpu_utils`
285*94c4a1e1SFrank Piva	echo -e "\t$RW($BS): jobs $JOBS, iops read ${TEST_RUN["read iops"]} write ${TEST_RUN["write iops"]}, $cpu_util"
286*94c4a1e1SFrank Piva
287*94c4a1e1SFrank Piva	RW="rw"
288*94c4a1e1SFrank Piva	BS=64k
289*94c4a1e1SFrank Piva	__run_fio_perf $DEV $BS $RW $JOBS $RT
290*94c4a1e1SFrank Piva	cpu_util=`__get_cpu_utils`
291*94c4a1e1SFrank Piva	echo -e "\t$RW($BS): jobs $JOBS, iops read ${TEST_RUN["read iops"]} write ${TEST_RUN["write iops"]}, $cpu_util"
292*94c4a1e1SFrank Piva
293*94c4a1e1SFrank Piva	RW="rw"
294*94c4a1e1SFrank Piva	BS=512k
295*94c4a1e1SFrank Piva	__run_fio_perf $DEV $BS $RW $JOBS $RT
296*94c4a1e1SFrank Piva	cpu_util=`__get_cpu_utils`
297*94c4a1e1SFrank Piva	echo -e "\t$RW($BS): jobs $JOBS, iops read ${TEST_RUN["read iops"]} write ${TEST_RUN["write iops"]}, $cpu_util"
298*94c4a1e1SFrank Piva
299*94c4a1e1SFrank Piva	echo ""
300*94c4a1e1SFrank Piva}
301*94c4a1e1SFrank Piva
302*94c4a1e1SFrank Piva__run_dev_perf()
303*94c4a1e1SFrank Piva{
304*94c4a1e1SFrank Piva	JOBS=$1
305*94c4a1e1SFrank Piva
306*94c4a1e1SFrank Piva	DEV=`__create_ublk_dev`
307*94c4a1e1SFrank Piva
308*94c4a1e1SFrank Piva	echo -e "\tublk add ${T_TYPE_PARAMS}, fio: ($DEV libaio dio io jobs($JOBS))..."
309*94c4a1e1SFrank Piva	__run_dev_perf_no_create "ublk" $JOBS $DEV
310*94c4a1e1SFrank Piva
311*94c4a1e1SFrank Piva	__remove_ublk_dev $DEV
312*94c4a1e1SFrank Piva}
313*94c4a1e1SFrank Piva
314*94c4a1e1SFrank Piva_create_null_image()
315*94c4a1e1SFrank Piva{
316*94c4a1e1SFrank Piva	echo ""
317*94c4a1e1SFrank Piva}
318*94c4a1e1SFrank Piva
319*94c4a1e1SFrank Piva_create_image()
320*94c4a1e1SFrank Piva{
321*94c4a1e1SFrank Piva	local type=$1
322*94c4a1e1SFrank Piva
323*94c4a1e1SFrank Piva	shift 1
324*94c4a1e1SFrank Piva
325*94c4a1e1SFrank Piva	eval _create_${type}_image $@
326*94c4a1e1SFrank Piva}
327*94c4a1e1SFrank Piva
328*94c4a1e1SFrank Piva_remove_null_image()
329*94c4a1e1SFrank Piva{
330*94c4a1e1SFrank Piva	echo "nothing" > /dev/null
331*94c4a1e1SFrank Piva}
332*94c4a1e1SFrank Piva
333*94c4a1e1SFrank Piva_remove_image()
334*94c4a1e1SFrank Piva{
335*94c4a1e1SFrank Piva	local type=$1
336*94c4a1e1SFrank Piva	shift 1
337*94c4a1e1SFrank Piva	eval _remove_${type}_image $@
338*94c4a1e1SFrank Piva}
339