单独对于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
Copy from provided data buffer (default buffer is stdin) to specified logical
blocks on the given device.
Options:
[ --start-block=
access
[ --block-count=
on device to access
[ --data-size=
[ --metadata-size=
[ --ref-tag=
[ --data=
[ --metadata=
[ --prinfo=
[ --app-tag-mask=
[ --app-tag=
[ --limited-retry, -l ] --- limit num. media access attempts
[ --force-unit-access, -f ] --- force device to commit data
before command completes
[ --dir-type=
[ --dir-spec=
write-only)
[ --dsm=
(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=
[ --ref-tag=
[ --metadata=
[ --prinfo=
[ --app-tag-mask=
[ --app-tag=
此处的-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
nvme format /dev/nvme0 -n 1 -l 3 -i 1或2
使用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之间传输的数据正确性.
使用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 功能的正确性,此时设备应该读出和写入成功.