nvme metadata end to end 简介和测试
单独对于Metadata的测试只是校验Metadata的写入和读出是否正常就可以了,在格式化成metadata的格式后,不会对lba的数据传输产生影响;metadata的写入读出也都正确.前者可以通过fio测试,后者可以通过nvme cli测试
Nvme协议中对于metadata的用法给出的是承载End to End protection,也就是将PI信息放在了Metadata中进行传输,这样的话每个lba都对应了一个pi信息,这个pi信息里面包含了这个lba的校验字段.
这是nvme Write命令的参数,Read命令和Write一样
Usage: nvme write <device> [OPTIONS]
Copy from provided data buffer (default buffer is stdin) to specified logical
blocks on the given device.
Options:
[ --start-block=<NUM>, -s <NUM> ] --- 64-bit addr of first block to
access
[ --block-count=<NUM>, -c <NUM> ] --- number of blocks (zeroes based)
on device to access
[ --data-size=<NUM>, -z <NUM> ] --- size of data in bytes
[ --metadata-size=<NUM>, -y <NUM> ] --- size of metadata in bytes
[ --ref-tag=<NUM>, -r <NUM> ] --- reference tag (for end to end PI)
[ --data=<FILE>, -d <FILE> ] --- data file
[ --metadata=<FILE>, -M <FILE> ] --- metadata file
[ --prinfo=<NUM>, -p <NUM> ] --- PI and check field
[ --app-tag-mask=<NUM>, -m <NUM> ] --- app tag mask (for end to end PI)
[ --app-tag=<NUM>, -a <NUM> ] --- app tag (for end to end PI)
[ --limited-retry, -l ] --- limit num. media access attempts
[ --force-unit-access, -f ] --- force device to commit data
before command completes
[ --dir-type=<NUM>, -T <NUM> ] --- directive type (for write-only)
[ --dir-spec=<NUM>, -S <NUM> ] --- directive specific (for
write-only)
[ --dsm=<NUM>, -D <NUM> ] --- dataset management attributes
(lower 16 bits)
[ --show-command, -v ] --- show command before sending
[ --dry-run, -w ] --- show command instead of sending
[ --latency, -t ] --- output latency statistics
Metadata-pi测试主要设计以下nvme cli Write/read参数
[ --metadata-size=<NUM>, -y <NUM> ] --- size of metadata in bytes
[ --ref-tag=<NUM>, -r <NUM> ] --- reference tag (for end to end PI)
[ --metadata=<FILE>, -M <FILE> ] --- metadata file
[ --prinfo=<NUM>, -p <NUM> ] --- PI and check field
[ --app-tag-mask=<NUM>, -m <NUM> ] --- app tag mask (for end to end PI)
[ --app-tag=<NUM>, -a <NUM> ] --- app tag (for end to end PI)
此处的-r参数,-m参数,-a参数都是填充进read/write命令中的,read/write命令中会有几个byte存放这几个参数,这几个参数被Controller用来和metadata中的PI信息做比较.
-M参数指定了metadata的文件,-y为Metadata的大小,-P参数为Metadata承载的是PI信息时,都应当进行那些字段的检测工作.
MetaData中的PI信息总共为8个Byte,分为三块,每个LBA都会附带这么一个PI信息,如下图.
Guard中存放当前lba的CRC-16的值,如果每个lba中的数据都相同是,那么他的CRC16值也是相同的,因为CRC16是由lba中的数据算出来的,在使用fio测试时,Host会将这个值算出来填充进Guard字段中.Controller在做校验时,会将这个Guard值和自己通过lba中的数据算出来的值做比较,相同则为正确.
Application Tag中也放着一个值,但是这个值对于Controller来说只是一个值而已,并不去理会这个值是怎么算出来的,Controller在做校验时,把Read/Write命令中自带的这个值(也就是nvme-cli read/write命令中的的-a -m参数)和Pi中的这个值做比较,相同则为正确.
Reference Tag中也放着一个值,这个值在NS被格式化成Type1和Type2格式的pi
时,是在命令中ILBRT字段的前提上随LBA递增的,在Type3的格式是,是一直保持不变的一个值.Type1和Type2的格式下Controller在校验时,会通过命令中ILBRT字段确定一个基础值,这个基础值代表本次命令中第一个LBA的Reference Tag值(一个Read/Write命令中可能会有多个LBA),后面的lba对应的PI信息中的Ref Tag字段,应该逐级递增.Controller会通过这个基础值和每个LBA对应的PI中的Ref Tag作比较,相同则为正确.在Type3下,每个lba对应的Ref Tag都是相同的,就等于命令中的ILBRT字段.
PRACT为0和1的区别(当前只讨论8byte metadata)
PRACT为0时,在Write时代表lba对应的PI信息会随着lba从Host写入到Controller再写入到Nand中,在Read时代表对应的PI信息会随着lba从nand读出到Controller上再读出到Host上.
PRACT为1时,在Write时,每个lba的pi信息是Controller自己添加上的,并不是由Host发下来的,在Read时,从Nand读出来的lba和pi信息,经过controller的校验之后,就被扔掉了,并不会将pi传输到Host上,或者传输到Host上也没什么意义.
信息测试流程为:
协议测试6.25.1
- 格式化为metadata & Pi 使能,使用type1或type2
nvme format /dev/nvme0 -n 1 -l 3 -i 1或2
- Fio写数据,使其将fio生成的pi信息写入到设备。
- 使用nvme read读一段lba,并将lba和metadata分别保存到文件中,读参数-p 0x01如下图代表check Reference Tag
使用nvme write,将上步读出来的文件再写回原来的lba,写参数-p 0x01.
以上第3步测试的是上图中PRACT为0时(因为此时-p 为 0x01)设备E2E PI 功能的正确性,此时设备应该读出和写入成功.
在read时,此时的metadata会由Nand Flash读到Controller中,再由Controller传输到Host中,PI验证的是从Nand Flash到Controllre之间传输的数据正确性.
在Write时,此时的metadata由Host生成并写入到Controller,再由Controller落到Nand Flash中,PI验证的是从Host到Controller之间传输的数据正确性.
- 使用read命令读一段lba,此时的参数-p 0x09(代表上图中为1001,PRACT=1,PRCHK=1),读上来的metadata内并不包含PI信息或者包含了PI信息也没什么用处,因为此时PRACT=1,E2E pi的模式为PI信息由Controller生成的.
使用write命令写一段lba,此时参数-p 0x09(代表上图中为1001,PRACT=1,PRCHK=1),写下去的pi信息是lba经过Controller时,由Controller生成的,所以Host在使用PRACT=1时的参数写lba时,Controller并不会检测这个metadata中的pi信息,Controller会重新生成PI信息并跟随lba落到nand中,在read此段lba时检测数据正确性.
以上第4步测试的是上图中PRACT为1时(因为此时-p 为 0x09)设备E2E PI 功能的正确性,此时设备应该读出和写入成功.