1# Introduction 2 3This directory contains a plug-in module for fio to enable use with SPDK. Fio is free software 4published under version 2 of the GPL license. 5 6## Compiling fio 7 8Clone the [fio source repository](https://github.com/axboe/fio) 9 10```bash 11 git clone https://github.com/axboe/fio 12 cd fio 13``` 14 15Compile the fio code and install: 16 17```bash 18 make 19 make install 20``` 21 22## Compiling SPDK 23 24Clone the [SPDK source repository](https://github.com/spdk/spdk) 25 26```bash 27 git clone https://github.com/spdk/spdk 28 cd spdk 29 git submodule update --init 30``` 31 32Then, run the SPDK configure script to enable fio (point it to the root of the fio repository): 33 34```bash 35 cd spdk 36 ./configure --with-fio=/path/to/fio/repo <other configuration options> 37``` 38 39Finally, build SPDK: 40 41```bash 42 make 43``` 44 45**Note to advanced users**: These steps assume you're using the DPDK submodule. If you are using your 46own version of DPDK, the fio plugin requires that DPDK be compiled with -fPIC. You can compile DPDK 47with -fPIC by modifying your DPDK configuration file and adding the line: 48 49```bash 50EXTRA_CFLAGS=-fPIC 51``` 52 53## Usage 54 55To use the SPDK fio plugin with fio, specify the plugin binary using LD_PRELOAD when running 56fio and set ioengine=spdk_bdev in the fio configuration file (see example_config.fio in the same 57directory as this README). Following example command assumes `fio` is in your system `$PATH` environment variable. 58 59```bash 60LD_PRELOAD=<path to spdk repo>/build/fio/spdk_bdev fio 61``` 62 63The fio configuration file must contain parameter pointing to a JSON configuration file containing SPDK bdev configuration: 64 65```bash 66spdk_json_conf=./app/fio/bdev/bdev.json 67``` 68 69You can specify which block device to run against by setting the filename parameter 70to the block device name: 71 72```bash 73filename=Malloc0 74``` 75 76Or for NVMe devices: 77 78```bash 79filename=Nvme0n1 80``` 81 82fio by default forks a separate process for every job. It also supports just spawning a separate 83thread in the same process for every job. The SPDK fio plugin is limited to this latter thread 84usage model, so fio jobs must also specify thread=1 when using the SPDK fio plugin. The SPDK fio 85plugin supports multiple threads - in this case, the "1" just means "use thread mode". 86 87fio also currently has a race condition on shutdown if dynamically loading the ioengine by specifying the 88engine's full path via the ioengine parameter - LD_PRELOAD is recommended to avoid this race condition. 89 90When testing random workloads, it is recommended to set norandommap=1. fio's random map 91processing consumes extra CPU cycles which will degrade performance over time with 92the fio_plugin since all I/O are submitted and completed on a single CPU core. 93 94### Step-by-step usage examples 95 96These examples assume you have built fio and SPDK with `--with-fio` option enabled. 97 98#### Using fio bdev plugin with local NVMe storage 99 100- Bind local NVMe drives to userspace driver 101 102- Run gen_nvme.sh script to create a JSON file with bdev subsystem configuration 103 104 ```bash 105 scripts/gen_nvme.sh --json-with-subsystems > /tmp/bdev.json 106 107 cat /tmp/bdev.json | jq 108 { 109 "subsystems": [ 110 { 111 "subsystem": "bdev", 112 "config": [ 113 { 114 "method": "bdev_nvme_attach_controller", 115 "params": { 116 "trtype": "PCIe", 117 "name": "Nvme0", 118 "traddr": "0000:0a:00.0" 119 } 120 }, 121 { 122 "method": "bdev_nvme_attach_controller", 123 "params": { 124 "trtype": "PCIe", 125 "name": "Nvme1", 126 "traddr": "0000:85:00.0" 127 } 128 } 129 ] 130 } 131 ] 132 } 133 ``` 134 135- Prepare fio configuration file 136 137 ```bash 138 cat /tmp/fio.conf 139 140 [global] 141 ioengine=/spdk/build/fio/spdk_bdev 142 spdk_json_conf=/tmp/bdev.json 143 144 thread=1 145 direct=1 146 group_reporting=1 147 148 bs=4k 149 rw=randread 150 rwmixread=70 151 time_based=1 152 runtime=10 153 norandommap=1 154 155 [filename0] 156 filename=Nvme0n1 157 filename=Nvme1n1 158 iodepth=8 159 ``` 160 161- Run fio with spdk bdev plugin 162 163 ```bash 164 /usr/src/fio/fio /tmp/fio.conf 165 ``` 166 167#### Using fio bdev plugin as NVMe-oF initiator with remote storage 168 169- Start SPDK NVMe-oF Target process and configure it with block devices and NVMe-oF subsystems 170 171 ```bash 172 build/bin/nvmf_tgt & 173 sleep 3 174 scripts/rpc.py bdev_malloc_create 10 512 -b Malloc0 175 scripts/rpc.py nvmf_create_transport -t TCP 176 scripts/rpc.py nvmf_create_subsystem nqn.2018-09.io.spdk:cnode1 -a -s S000001 177 scripts/rpc.py nvmf_subsystem_add_listener nqn.2018-09.io.spdk:cnode1 -t tcp -f ipv4 -s 4420 -a 10.0.0.1 178 scripts/rpc.py nvmf_subsystem_add_ns nqn.2018-09.io.spdk:cnode1 Malloc0 179 ``` 180 181- Run gen_nvme.sh script to prepare a JSON file containing bdev subsystem configuration 182 for initiator which will allow it to connect to target 183 184 ```bash 185 scripts/gen_nvme.sh --json-with-subsystems --mode=remote \ 186 --trid=tcp:10.0.0.1:4420:nqn.2018-09.io.spdk:cnode1 > /tmp/bdev.json 187 188 cat /tmp/bdev.json | jq 189 { 190 "subsystems": [ 191 { 192 "subsystem": "bdev", 193 "config": [ 194 { 195 "method": "bdev_nvme_attach_controller", 196 "params": { 197 "trtype": "tcp", 198 "adrfam": "IPv4", 199 "name": "Nvme0", 200 "subnqn": "nqn.2018-09.io.spdk:cnode1", 201 "traddr": "10.0.0.1", 202 "trsvcid": "4420" 203 } 204 } 205 ] 206 } 207 ] 208 } 209 ``` 210 211- Prepare fio configuration file 212 213 ```bash 214 cat /tmp/fio.conf 215 216 [global] 217 ioengine=/spdk/build/fio/spdk_bdev 218 spdk_json_conf=/tmp/bdev.json 219 220 thread=1 221 direct=1 222 group_reporting=1 223 224 bs=4k 225 rw=randread 226 rwmixread=70 227 time_based=1 228 runtime=10 229 norandommap=1 230 231 [filename0] 232 filename=Nvme0n1 233 iodepth=8 234 ``` 235 236- Run fio bdev plugin as initiator 237 238 ```bash 239 /usr/src/fio/fio /tmp/fio.conf 240 ``` 241 242## Zoned Block Devices 243 244SPDK has a zoned block device API (bdev_zone.h) which currently supports Open-channel SSDs, 245NVMe Zoned Namespaces (ZNS), and the virtual zoned block device SPDK module. 246 247If you wish to run fio against a SPDK zoned block device, you can use the fio option: 248 249```bash 250zonemode=zbd 251``` 252 253It is recommended to use a fio version newer than version 3.26, if using --numjobs > 1. 254If using --numjobs=1, fio version >= 3.23 should suffice. 255 256See zbd_example.fio in this directory for a zoned block device example config. 257 258### Maximum Open Zones 259 260Most zoned block devices have a resource constraint on the amount of zones which can be in an opened 261state at any point in time. It is very important to not exceed this limit. 262 263You can control how many zones fio will keep in an open state by using the 264`--max_open_zones` option. 265 266If you use a fio version newer than 3.26, fio will automatically detect and set the proper value. 267If you use an old version of fio, make sure to provide the proper --max_open_zones value yourself. 268 269### Maximum Active Zones 270 271Zoned block devices may also have a resource constraint on the number of zones that can be active at 272any point in time. Unlike `max_open_zones`, fio currently does not manage this constraint, and 273there is thus no option to limit it either. 274 275Since the max active zones limit (by definition) has to be greater than or equal to the max open 276zones limit, the easiest way to work around that fio does not manage this constraint, is to start 277with a clean state each run (except for read-only workloads), by resetting all zones before fio 278starts running its jobs by using the engine option: 279 280```bash 281--initial_zone_reset=1 282``` 283 284### Zone Append 285 286When running fio against a zoned block device you need to specify --iodepth=1 to avoid 287"Zone Invalid Write: The write to a zone was not at the write pointer." I/O errors. 288However, if your zoned block device supports Zone Append, you can use the engine option: 289 290```bash 291--zone_append=1 292``` 293 294To send zone append commands instead of write commands to the zoned block device. 295When using zone append, you will be able to specify a --iodepth greater than 1. 296