xref: /spdk/scripts/fio-wrapper (revision dbac81ecffced70062c2dc9306609b0a8593bd6f)
119f0c9a0SMichal Berger#!/usr/bin/env bash
2eb53c232Spaul luse#  SPDX-License-Identifier: BSD-3-Clause
3eb53c232Spaul luse#  Copyright (C) 2021 Intel Corporation
4eb53c232Spaul luse#  All rights reserved.
5eb53c232Spaul luse
619f0c9a0SMichal Bergerrootdir=$(readlink -f "$(dirname "$0")/../")
719f0c9a0SMichal Berger
819f0c9a0SMichal Bergershopt -s nullglob extglob
919f0c9a0SMichal Berger
1019f0c9a0SMichal Bergerfio_config() {
1119f0c9a0SMichal Berger	local devs=("$@") dev
1219f0c9a0SMichal Berger
1319f0c9a0SMichal Berger	cat <<- FIO
1419f0c9a0SMichal Berger		[global]
1519f0c9a0SMichal Berger		thread=1
1619f0c9a0SMichal Berger		invalidate=1
1719f0c9a0SMichal Berger		rw=$testtype
1819f0c9a0SMichal Berger		time_based=1
1919f0c9a0SMichal Berger		runtime=$runtime
2019f0c9a0SMichal Berger		ioengine=libaio
2119f0c9a0SMichal Berger		direct=1
2219f0c9a0SMichal Berger		bs=$blocksize
2319f0c9a0SMichal Berger		iodepth=$iodepth
2419f0c9a0SMichal Berger		norandommap=$((verify == 1 ? 0 : 1))
2519f0c9a0SMichal Berger		numjobs=$numjobs
264e996120SKarol Latecki		${rwmixread:+rwmixread=$rwmixread}
2719f0c9a0SMichal Berger	FIO
2819f0c9a0SMichal Berger
2919f0c9a0SMichal Berger	if ((verify == 1)); then
3019f0c9a0SMichal Berger		cat <<- FIO
31935d6cafSKarol Latecki			verify_dump=1
32935d6cafSKarol Latecki			verify_backlog=512
33935d6cafSKarol Latecki			verify_state_save=0
3419f0c9a0SMichal Berger			do_verify=$verify
3519f0c9a0SMichal Berger			verify=crc32c-intel
3619f0c9a0SMichal Berger		FIO
3719f0c9a0SMichal Berger	fi
3819f0c9a0SMichal Berger
3919f0c9a0SMichal Berger	for dev in "${!devs[@]}"; do
4019f0c9a0SMichal Berger		cat <<- FIO
4119f0c9a0SMichal Berger			[job$dev]
4219f0c9a0SMichal Berger			filename=/dev/${devs[dev]}
4319f0c9a0SMichal Berger		FIO
4419f0c9a0SMichal Berger	done
4519f0c9a0SMichal Berger}
4619f0c9a0SMichal Berger
4719f0c9a0SMichal Bergerrun_fio() {
483dcc7668SKarol Latecki	local output_args
493dcc7668SKarol Latecki	if [[ -n "$output" ]]; then
503dcc7668SKarol Latecki		output_args=("--group_reporting=1" "--output-format=json" "--output=$output")
513dcc7668SKarol Latecki	fi
523dcc7668SKarol Latecki	fio_config "$@" | fio "${output_args[@]}" -
5319f0c9a0SMichal Berger}
5419f0c9a0SMichal Berger
5519f0c9a0SMichal Bergerget_iscsi() {
5619f0c9a0SMichal Berger	while read -r; do
5719f0c9a0SMichal Berger		[[ $REPLY =~ "Attached scsi disk "(sd[a-z]+) ]] && echo "${BASH_REMATCH[1]}"
5819f0c9a0SMichal Berger	done < <(iscsiadm -m session -P 3)
5919f0c9a0SMichal Berger}
6019f0c9a0SMichal Berger
6119f0c9a0SMichal Bergerget_nvme() {
6219f0c9a0SMichal Berger	local blocks nvme nvme_sub
63269737b9SMichal Berger	for nvme in /sys/block/nvme*; do
64269737b9SMichal Berger		# Some kernels expose hidden fabrics devices ("nvmeXcXnX") under sysfs - skip them.
65269737b9SMichal Berger		if (($(< "$nvme/hidden") == 1)); then
66269737b9SMichal Berger			continue
67269737b9SMichal Berger		fi
68269737b9SMichal Berger		# Make sure we touch only the block devices which belong to bdev subsystem.
69269737b9SMichal Berger		[[ $(< "$nvme/device/model") == "SPDK bdev Controller"* ]] || continue
70269737b9SMichal Berger		blocks+=("${nvme##*/}")
7119f0c9a0SMichal Berger	done
723c578739SMichal Berger	printf '%s\n' "${blocks[@]}"
7319f0c9a0SMichal Berger}
7419f0c9a0SMichal Berger
751c0e38bbSKarol Lateckiget_ublk() {
761c0e38bbSKarol Latecki	local blocks
771c0e38bbSKarol Latecki	blocks=(/sys/block/ublk*)
781c0e38bbSKarol Latecki	printf '%s\n' "${blocks[@]##*/}"
791c0e38bbSKarol Latecki}
801c0e38bbSKarol Latecki
8119f0c9a0SMichal Bergerget_devices() {
8219f0c9a0SMichal Berger	local devs=("$@")
8319f0c9a0SMichal Berger
8419f0c9a0SMichal Berger	if ((${#devs[@]} == 0)); then
8519f0c9a0SMichal Berger		case "$protocol" in
8619f0c9a0SMichal Berger			iscsi) devs=($(get_iscsi)) ;;
8719f0c9a0SMichal Berger			nvmf) devs=($(get_nvme)) ;;
881c0e38bbSKarol Latecki			ublk) devs=($(get_ublk)) ;;
8919f0c9a0SMichal Berger			*) ;;
9019f0c9a0SMichal Berger		esac
9119f0c9a0SMichal Berger	fi
9219f0c9a0SMichal Berger	printf '%s\n' "${devs[@]}"
9319f0c9a0SMichal Berger}
9419f0c9a0SMichal Berger
9519f0c9a0SMichal Bergerconfigure_devices() {
9619f0c9a0SMichal Berger	local devs=("$@") dev qd
9719f0c9a0SMichal Berger
9843aca604SMichal Berger	if [[ -e $rootdir/scripts/sync_dev_uevents.sh ]]; then
9943aca604SMichal Berger		"$rootdir/scripts/sync_dev_uevents.sh" block/disk "${devs[@]}"
10043aca604SMichal Berger	fi > /dev/null
10143aca604SMichal Berger
10219f0c9a0SMichal Berger	for dev in "${devs[@]}"; do
10319f0c9a0SMichal Berger		qd=128
10419f0c9a0SMichal Berger		# Disable all merge tries"
10519f0c9a0SMichal Berger		echo 2 > "/sys/block/$dev/queue/nomerges"
10619f0c9a0SMichal Berger		# FIXME: nr_requests already has its default value at 128. Also, when no
10719f0c9a0SMichal Berger		# scheduler is associated with the device this value cannot be changed
10819f0c9a0SMichal Berger		# and is automatically adjusted as well.
10919f0c9a0SMichal Berger		# echo 128 > "/sys/block/$dev/queue/nr_requests"
11019f0c9a0SMichal Berger		if [[ -e /sys/block/$dev/device/queue_depth ]]; then
11119f0c9a0SMichal Berger			# FIXME: Is this really needed though? Can't we use the default? This is not
11219f0c9a0SMichal Berger			# very deterministic as depending on the device we may end up with different
11319f0c9a0SMichal Berger			# qd in the range of 1-128.
11419f0c9a0SMichal Berger			while ((qd > 0)) && ! echo "$qd" > "/sys/block/$dev/device/queue_depth"; do
11519f0c9a0SMichal Berger				((--qd))
11619f0c9a0SMichal Berger			done 2> /dev/null
11719f0c9a0SMichal Berger			if ((qd == 0)); then
11819f0c9a0SMichal Berger				printf 'Failed to set queue_depth (%s)\n' "$dev"
11919f0c9a0SMichal Berger				return 1
12019f0c9a0SMichal Berger			fi
12119f0c9a0SMichal Berger			printf 'queue_depth set to %u (%s)\n' "$qd" "$dev"
12219f0c9a0SMichal Berger		else
12319f0c9a0SMichal Berger			printf 'Could not set queue depth (%s)\n' "$dev" >&2
12419f0c9a0SMichal Berger		fi
125*dbac81ecSMichal Berger		if [[ -e /sys/block/$dev/queue/scheduler ]]; then
12619f0c9a0SMichal Berger			echo none > "/sys/block/$dev/queue/scheduler"
127*dbac81ecSMichal Berger		fi
12819f0c9a0SMichal Berger	done
12919f0c9a0SMichal Berger}
13019f0c9a0SMichal Berger
13119f0c9a0SMichal Berger# Defaults
13219f0c9a0SMichal Bergerblocksize=4096
13319f0c9a0SMichal Bergeriodepth=1
13419f0c9a0SMichal Bergernumjobs=1
13519f0c9a0SMichal Bergerprotocol="nvmf"
13619f0c9a0SMichal Bergerruntime=1
13719f0c9a0SMichal Bergertesttype="read"
1383dcc7668SKarol Lateckioutput=""
1394e996120SKarol Lateckirwmixread=""
14019f0c9a0SMichal Bergerverify=0
14119f0c9a0SMichal Berger
14219f0c9a0SMichal Berger# Keep short args compatible with fio.py
1434e996120SKarol Lateckiwhile getopts :i:d:n:p:r:t:o:m:v arg; do
14419f0c9a0SMichal Berger	case "$arg" in
14519f0c9a0SMichal Berger		i) blocksize=$OPTARG ;;
14619f0c9a0SMichal Berger		d) iodepth=$OPTARG ;;
14719f0c9a0SMichal Berger		n) numjobs=$OPTARG ;;
14819f0c9a0SMichal Berger		p) protocol=$OPTARG ;;
14919f0c9a0SMichal Berger		r) runtime=$OPTARG ;;
15019f0c9a0SMichal Berger		t) testtype=$OPTARG ;;
1513dcc7668SKarol Latecki		o) output=$OPTARG ;;
1524e996120SKarol Latecki		m) rwmixread=$OPTARG ;;
15319f0c9a0SMichal Berger		v) verify=1 ;;
15419f0c9a0SMichal Berger		*) ;;
15519f0c9a0SMichal Berger	esac
15619f0c9a0SMichal Bergerdone
15719f0c9a0SMichal Bergershift $((OPTIND - 1))
15819f0c9a0SMichal Berger
15919f0c9a0SMichal Bergerdevices=($(get_devices "$@"))
16019f0c9a0SMichal Bergerif ((${#devices[@]} == 0)); then
16119f0c9a0SMichal Berger	printf '* No devices were found for the test, aborting\n' >&2
16219f0c9a0SMichal Berger	exit 1
16319f0c9a0SMichal Bergerfi
16419f0c9a0SMichal Berger
16519f0c9a0SMichal Bergerfio_config "${devices[@]}"
16619f0c9a0SMichal Bergerconfigure_devices "${devices[@]}" && run_fio "${devices[@]}"
167