README.md
1# FIO plugin
2
3## Compiling fio
4
5First, clone the fio source repository from https://github.com/axboe/fio
6
7```bash
8 git clone https://github.com/axboe/fio
9```
10
11Then check out the latest fio version and compile the code:
12
13```bash
14 make
15```
16
17## Compiling SPDK
18
19First, clone the SPDK source repository from https://github.com/spdk/spdk
20
21```bash
22 git clone https://github.com/spdk/spdk
23 git submodule update --init
24```
25
26Then, run the SPDK configure script to enable fio (point it to the root of the fio repository):
27
28```bash
29 cd spdk
30 ./configure --with-fio=/path/to/fio/repo <other configuration options>
31```
32
33Finally, build SPDK:
34
35```bash
36 make
37```
38
39**Note to advanced users**: These steps assume you're using the DPDK submodule. If you are using your
40own version of DPDK, the fio plugin requires that DPDK be compiled with -fPIC. You can compile DPDK
41with -fPIC by modifying your DPDK configuration file and adding the line:
42
43```bash
44EXTRA_CFLAGS=-fPIC
45```
46
47## Usage
48
49To use the SPDK fio plugin with fio, specify the plugin binary using LD_PRELOAD when running
50fio and set ioengine=spdk in the fio configuration file (see example_config.fio in the same
51directory as this README).
52
53```bash
54LD_PRELOAD=<path to spdk repo>/build/fio/spdk_nvme fio
55```
56
57To select NVMe devices, you pass an SPDK Transport Identifier string as the filename. These are in the
58form:
59
60```bash
61filename=key=value [key=value] ... ns=value
62```
63
64Specifically, for local PCIe NVMe devices it will look like this:
65
66```bash
67filename=trtype=PCIe traddr=0000.04.00.0 ns=1
68```
69
70And remote devices accessed via NVMe over Fabrics will look like this:
71
72```bash
73filename=trtype=RDMA adrfam=IPv4 traddr=192.168.100.8 trsvcid=4420 ns=1
74```
75
76**Note**: The specification of the PCIe address should not use the normal ':'
77and instead only use '.'. This is a limitation in fio - it splits filenames on
78':'. Also, the NVMe namespaces start at 1, not 0, and the namespace must be
79specified at the end of the string.
80
81fio by default forks a separate process for every job. It also supports just spawning a separate
82thread in the same process for every job. The SPDK fio plugin is limited to this latter thread
83usage model, so fio jobs must also specify thread=1 when using the SPDK fio plugin. The SPDK fio
84plugin supports multiple threads - in this case, the "1" just means "use thread mode".
85
86fio also currently has a race condition on shutdown if dynamically loading the ioengine by specifying the
87engine's full path via the ioengine parameter - LD_PRELOAD is recommended to avoid this race condition.
88
89When testing random workloads, it is recommended to set norandommap=1. fio's random map
90processing consumes extra CPU cycles which will degrade performance over time with
91the fio_plugin since all I/O are submitted and completed on a single CPU core.
92
93When testing FIO on multiple NVMe SSDs with SPDK plugin, it is recommended to use multiple jobs in FIO configurion.
94It has been observed that there are some performance gap between FIO(with SPDK plugin enabled) and SPDK perf
95(app/spdk_nvme_perf) on testing multiple NVMe SSDs. If you use one job(i.e., use one CPU core) configured for
96FIO test, the performance is worse than SPDK perf (also using one CPU core) against many NVMe SSDs. But if you use
97multiple jobs for FIO test, the performance of FIO is similar with SPDK perf. After analyzing this phenomenon, we
98think that is caused by the FIO architecture. Mainly FIO can scale with multiple threads (i.e., using CPU cores),
99but it is not good to use one thread against many I/O devices.
100
101## End-to-end Data Protection (Optional)
102
103Running with PI setting, following settings steps are required.
104First, format device namespace with proper PI setting. For example:
105
106```bash
107 nvme format /dev/nvme0n1 -l 1 -i 1 -p 0 -m 1
108```
109
110In fio configure file, add PRACT and set PRCHK by flags(GUARD|REFTAG|APPTAG) properly. For example:
111
112```bash
113pi_act=0
114pi_chk=GUARD
115```
116
117Blocksize should be set as the sum of data and metadata. For example, if data blocksize is 512 Byte, host generated
118PI metadata is 8 Byte, then blocksize in fio configure file should be 520 Byte:
119
120```bash
121bs=520
122```
123
124The storage device may use a block format that requires separate metadata (DIX). In this scenario, the fio_plugin
125will automatically allocate an extra 4KiB buffer per I/O to hold this metadata. For some cases, such as 512 byte
126blocks with 32 metadata bytes per block and a 128KiB I/O size, 4KiB isn't large enough. In this case, the
127`md_per_io_size` option may be specified to increase the size of the metadata buffer.
128
129Expose two options 'apptag' and 'apptag_mask', users can change them in the configuration file when using
130application tag and application tag mask in end-to-end data protection. Application tag and application
131tag mask are set to 0x1234 and 0xFFFF by default.
132
133## VMD (Optional)
134
135To enable VMD enumeration add enable_vmd flag in fio configuration file:
136
137```bash
138enable_vmd=1
139```
140
141## ZNS
142
143To use Zoned Namespaces then build the io-engine against, and run using, a fio version >= 3.23 and add:
144
145```bash
146zonemode=zbd
147```
148
149To your fio-script, also have a look at script-examples provided with fio:
150
151```bash
152fio/examples/zbd-seq-read.fio
153fio/examples/zbd-rand-write.fio
154```
155
156### Maximum Open Zones
157
158Zoned Namespaces has a resource constraint on the amount of zones which can be in an opened state at
159any point in time. You can control how many zones fio will keep in an open state by using the
160``--max_open_zones`` option.
161
162If you use a fio version newer than 3.26, fio will automatically detect and set the proper value.
163If you use an old version of fio, make sure to provide the proper --max_open_zones value yourself.
164
165### Maximum Active Zones
166
167Zoned Namespaces has a resource constraint on the number of zones that can be active at any point in
168time. Unlike ``max_open_zones``, then fio currently do not manage this constraint, and there is thus
169no option to limit it either.
170
171When running with the SPDK/NVMe fio io-engine you can be exposed to error messages, in the form of
172completion errors, with the NVMe status code of 0xbd ("Too Many Active Zones"). To work around this,
173then you can reset all zones before fio start running its jobs by using the engine option:
174
175```bash
176--initial_zone_reset=1
177```
178
179### Zone Append
180
181When running FIO against a Zoned Namespace you need to specify --iodepth=1 to avoid
182"Zone Invalid Write: The write to a zone was not at the write pointer." I/O errors.
183However, if your controller supports Zone Append, you can use the engine option:
184
185```bash
186--zone_append=1
187```
188
189To send zone append commands instead of write commands to the controller.
190When using zone append, you will be able to specify a --iodepth greater than 1.
191
192### Shared Memory Increase
193
194If your device has a lot of zones, fio can give you errors such as:
195
196```bash
197smalloc: OOM. Consider using --alloc-size to increase the shared memory available.
198```
199
200This is because fio needs to allocate memory for the zone-report, that is, retrieve the state of
201zones on the device including auxiliary accounting information. To solve this, then you can follow
202fio's advice and increase ``--alloc-size``.
203
204## FDP
205
206To use FDP enabled device build and run the io-engine against fio version >= 3.34 and add:
207
208```bash
209fdp=1
210```
211
212to your fio-script, also have a look at script-example provided with fio:
213
214```bash
215fio/examples/uring-cmd-fdp.fio
216```
217