1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2021 Intel Corporation 4# All rights reserved. 5 6rootdir=$(readlink -f "$(dirname "$0")/../") 7 8shopt -s nullglob extglob 9 10fio_config() { 11 local devs=("$@") dev 12 13 cat <<- FIO 14 [global] 15 thread=1 16 invalidate=1 17 rw=$testtype 18 time_based=1 19 runtime=$runtime 20 ioengine=libaio 21 direct=1 22 bs=$blocksize 23 iodepth=$iodepth 24 norandommap=$((verify == 1 ? 0 : 1)) 25 numjobs=$numjobs 26 verify_dump=1 27 verify_backlog=512 28 verify_state_save=0 29 FIO 30 31 if ((verify == 1)); then 32 cat <<- FIO 33 do_verify=$verify 34 verify=crc32c-intel 35 FIO 36 fi 37 38 for dev in "${!devs[@]}"; do 39 cat <<- FIO 40 [job$dev] 41 filename=/dev/${devs[dev]} 42 FIO 43 done 44} 45 46run_fio() { 47 fio_config "$@" | fio - 48} 49 50get_iscsi() { 51 while read -r; do 52 [[ $REPLY =~ "Attached scsi disk "(sd[a-z]+) ]] && echo "${BASH_REMATCH[1]}" 53 done < <(iscsiadm -m session -P 3) 54} 55 56get_nvme() { 57 local blocks nvme nvme_sub 58 for nvme in /sys/block/nvme*; do 59 # Some kernels expose hidden fabrics devices ("nvmeXcXnX") under sysfs - skip them. 60 if (($(< "$nvme/hidden") == 1)); then 61 continue 62 fi 63 # Make sure we touch only the block devices which belong to bdev subsystem. 64 [[ $(< "$nvme/device/model") == "SPDK bdev Controller"* ]] || continue 65 blocks+=("${nvme##*/}") 66 done 67 printf '%s\n' "${blocks[@]}" 68} 69 70get_devices() { 71 local devs=("$@") 72 73 if ((${#devs[@]} == 0)); then 74 case "$protocol" in 75 iscsi) devs=($(get_iscsi)) ;; 76 nvmf) devs=($(get_nvme)) ;; 77 *) ;; 78 esac 79 fi 80 printf '%s\n' "${devs[@]}" 81} 82 83configure_devices() { 84 local devs=("$@") dev qd 85 86 if [[ -e $rootdir/scripts/sync_dev_uevents.sh ]]; then 87 "$rootdir/scripts/sync_dev_uevents.sh" block/disk "${devs[@]}" 88 fi > /dev/null 89 90 for dev in "${devs[@]}"; do 91 qd=128 92 # Disable all merge tries" 93 echo 2 > "/sys/block/$dev/queue/nomerges" 94 # FIXME: nr_requests already has its default value at 128. Also, when no 95 # scheduler is associated with the device this value cannot be changed 96 # and is automatically adjusted as well. 97 # echo 128 > "/sys/block/$dev/queue/nr_requests" 98 if [[ -e /sys/block/$dev/device/queue_depth ]]; then 99 # FIXME: Is this really needed though? Can't we use the default? This is not 100 # very deterministic as depending on the device we may end up with different 101 # qd in the range of 1-128. 102 while ((qd > 0)) && ! echo "$qd" > "/sys/block/$dev/device/queue_depth"; do 103 ((--qd)) 104 done 2> /dev/null 105 if ((qd == 0)); then 106 printf 'Failed to set queue_depth (%s)\n' "$dev" 107 return 1 108 fi 109 printf 'queue_depth set to %u (%s)\n' "$qd" "$dev" 110 else 111 printf 'Could not set queue depth (%s)\n' "$dev" >&2 112 fi 113 echo none > "/sys/block/$dev/queue/scheduler" 114 done 115} 116 117# Defaults 118blocksize=4096 119iodepth=1 120numjobs=1 121protocol="nvmf" 122runtime=1 123testtype="read" 124verify=0 125 126# Keep short args compatible with fio.py 127while getopts :i:d:n:p:r:t:v arg; do 128 case "$arg" in 129 i) blocksize=$OPTARG ;; 130 d) iodepth=$OPTARG ;; 131 n) numjobs=$OPTARG ;; 132 p) protocol=$OPTARG ;; 133 r) runtime=$OPTARG ;; 134 t) testtype=$OPTARG ;; 135 v) verify=1 ;; 136 *) ;; 137 esac 138done 139shift $((OPTIND - 1)) 140 141devices=($(get_devices "$@")) 142if ((${#devices[@]} == 0)); then 143 printf '* No devices were found for the test, aborting\n' >&2 144 exit 1 145fi 146 147fio_config "${devices[@]}" 148configure_devices "${devices[@]}" && run_fio "${devices[@]}" 149