端到端数据保护(End-to-end Data Protection)将数据的完整性保护范围从SSD内部延伸到外部链路,以防止静默错误(静默错误:指的是存储在SSD中的数据发生了损坏或错误,但SSD的控制器本身没有检测到这个错误。简单的说就是,当你读取数据时,返回给你的是错误数据,但SSD却没有报告任何错误,认为操作是成功的)产生——通过对逻辑块数据(Logical Block Data,通常指用户数据)添加额外的PI(Protection Information,保护信息,如CRC),使其作为数据的元数据被一同传输,主机端和NVM控制器都可以在接收到数据后,根据PI的内容对数据完整性进行校验,以确定这些数据是否有效。
Protection Information
PI在Metadata中的存放方式有两种,在进行Format命令操作并开启端到端数据保护功能时需要指定PI在Metadata中的存放位置。
1、位于Metadata的头部
2、位于Metadata的尾部
注意:
-
-
- 如果Metadata Size=PI Size,则只需要提供对User Data的保护即可
- 如果Metadata Size>PI Size,如果PI位于Metadata头部,只需要提供对User Data的保护;如果位于Metadata的尾部,则需要提供对User Data和PI前面的所有Metadata的保护。
-
PI信息包含了以下字段信息:
-
- Guard:是基于用户数据计算得出的CRC-16校验信息,计算方法在SBC-3中定义;
-
- Application Tag:由上层应用指定,无需NVM控制器处理,也可用于禁用PI的检查;
-
- Reference Tag:绑定数据和其所属的逻辑块地址 (LBA),确保数据在整个传输路径中,始终与正确的LBA相关联,防止数据被错误地放置到不属于它的LBA位置,不存储在NAND上,也可用于禁用PI的检查;
- Storage Tag:在SSD内部,确保数据被写入到正确的物理位置,防止因SSD控制器固件错误(尤其是FTL闪存转换层映射错误)导致的数据被错误地覆盖到属于另一个LBA的物理位置上,从而造成静默数据损坏,会存放在Nand上,也可用于禁用PI的检查;
Protection Information Format
格式1——16位保护信息
PI Format在NVMe 1.x Spec版本时只有一个数据格式:
由2字节的Guard字段、2字节的Application Tag字段和4个字节的Reference Tag字段组成,共8个字节。

而在NVMe 2.x Spec版本之后,因为了Storage Tag,即Reference Tag部分或全部替换为Storage Tag,其替换的大小由STS(Storage Tag Size位于I/O Command Set Specific Identify Namespace Data Structure (CNS 05h)中的Extended LBA Format Data Structure, NVM Command Set Specific Bit 6:0)决定。

格式2——32位保护信息
32位保护信息仅适用于LBA大于或等于4KiB的命名空间,总长度增加至16个字节:
Guard字段增加为4个字节,为基于用户数据计算得出的32位CRC;Application Tag字段不变,仍为2个字节;Storage and Reference Space字段增加至10个字节

32的Guard通过CRC-32C(Castagnoli)算法,基于1EDC6F41h生成多项式得出。下面是32位CRC的具体示例:
|
Logical Block Contents
|
32b Guard Field Value
|
|
4K字节数据,每个字节均为00h
|
98F94189h
|
|
4K字节数据,每个字节均为FFh
|
25C1FE13h
|
|
4K字节数据,从00h到FFh依次递增,重复进行循环
|
9C71FE32h
|
|
4K字节数据,从FFh到00h依次递减,重复进行循环
|
214941A8h
|
格式3——64位保护信息
64位保护信息同样只仅适用于LBA大于或等于4K的命名空间,总长度同为16个字节:
Guard字段增加为8个字节,为基于逻辑块数据计算得出的64位CRC;Application Tag字段不变,仍为2个字节;Storage and Reference Space字段调整为6个字节。

64的Guard通过Rocksoft™ CRC算法生成,生成步骤见NVM Command Set Specification Revision 1.0*
Storage and Reference Space
在NVMe 2.x Spec版本之后,引入了Storage Tag;在Idfy NS status中的STS字段将PI中的Storage and Reference Space分离为Storage Tag和Logical Block Reference Tag。
- 如果STS=0,则不包含Storage Tag;
- 如果STS!=0,Storage and Reference Space最高有效位相同数量的Bits为Storage Tag,剩余部分为最低有效位,对应Referce Tag;
- 如果STS值等于Storage and Reference Space大小相同,则不会包含Reference Tag。

IO写命令SQE中的LBST和ILBRT与每笔User Data对应的Metadata中的Storage Tag和Reference Tag之间的关系如下:
- ILBRT → Reference Tag:按逻辑块递增,一个ILBRT起始值衍生出连续RefTag序列,Metadata中存储RefTag数组。
- LBST → Storage Tag:按物理页偏移,一个LBST基础值衍生出连续ST序列(ST = LBST + 页索引)。
- Metadata结构:每物理页独立存储:
- 1个Storage Tag(由LBST+页偏移计算)
- N个Reference Tag(N = 物理页大小/逻辑块大小)
对于在启动了端到端的命令空间处理的I/O命令,如果定义了Storage Tag,则需要再IO命令的SQE中添加LBST(Logical Block Storage Tag,逻辑块存储标记)或ELBST(Expected Logical Block Storage Tag,预期得到的逻辑块存储标记)与ILBRT(Initial Logical Block Reference Tag,初始逻辑块参考标记)或EILBRT(Expected Initial Logical Block Reference Tag,预期得到的初始逻辑块参考标记)字段进行检查

LBST、ELBST、ILBRT和EILBRT字段的最小和最大比特数如下所示:
|
STS Value |
LBST/ELBST Bit Size
|
ILBRT/EILBRT Bit Size
| |
|
16b Guard Protection Information
| |||
|
最小值
|
0
|
0
|
32
|
|
最大值
|
32
|
32
|
0
|
|
32b Guard Protection Information
| |||
|
最小值
|
16
|
16
|
64
|
|
最大值
|
64
|
64
|
16
|
|
64b Guard Protection Information
| |||
|
最小值
|
0
|
0
|
48
|
|
最大值
|
48
|
48
|
0
|
LBST/ELBST Size为0时,不存在Storage Tag,也无需检查LBST和ELBST;
ILBRT/EILBRT Size为0时,不存在Reference Tag,也无需检查ILBRT和EILBRT。
PRACT Bit
PRACT Bit位于IO SQE中PRINFO中bit 3,它决定了在读命令和写命令等IO命令执行期间,指定了PI是有Host生成还是Controller生成,并决定了数据在读取时是否将PI返回给Host。
- IO Write命令中,如果NS空间进行格式化的时候开启了端到端的数据保护功能:
-
- PRACT=0;由主机端生成的PI,NVMe控制器对接受到的PI进行检查,如果检查到错误,将以端到端检查错误代码(End-to-end Guard Check Error-82h, End-to-end Application Tag Check Error-83h,End-to-end Storage Tag Check Error-88h or End-to-end Reference Tag Check Error-84h)返回CQ。
- PRACT=1,由NVM控制器生成PI,不论PRCHK如何要求,NVM控制器均无需对主机发来的PI进行检查。
- 如果Metadata和PI大小相同,NVM控制器只需要基于接收到的User Data计算生成PI并添加至逻辑块数据末尾,写入NVM介质中;
- 如果Metadata大于PI,NVM控制器根据PI在Metadata中的存放位置,如果置于开头,只需要基于User Data重新计算生成PI并对主机发来的PI加以替换,如果置于末尾,则需要基于User Data和PI前面的Metadata计算生成新的PI,并对主机发来的PI加以替换。
- IO Read命令中,如果NS空间进行格式化的时候开启了端到端的数据保护功能:
-
- PRACT=0,User Data和Metadata(包含PI)将被传输至主机的缓冲区。当这些数据经过NVM控制器时,控制器会对PI进行检查,如果有错,将以错误代码的形式完成本次读命令。
- PRACT=1,NVM控制器同样会进行PI的检查
- 如果校验失败,返回错误代码并终止读命令
- 如果校验成功:
- Metadata大小和PI相同,只发送User Data至主机即可,不需要发送PI;
- Metadata大于PI,则发送User Data和Metadata(包含PI)至主机。
- Write-zeroes命令中,如果NS空间进行格式化的时候开启了端到端的数据保护功能:(只讨论DEAC字段为0的情况,因为当DEAC为1时,是直接Erase盘上数据,则Metadata数据都应该为全F)
- 对于此命令,如果存在非PI相关的Metadata,则所有字段应该清”0“
- PRACT=0,则此命令的PI应该全部为0
- PRACT=1,则取决于LBAT、LBRT、LBATM等参数(一般是Guard为0,Application Guard=全F,Storage and Reference Space为全F)
PRCHK Bit
指定PI的检查方式,检查Guard、Application、Storage and Reference Space Tag中的一个或多个;当且仅当PRACT=0时,数据的接收方需要对发送来的PI进行校验。
- IO Write命令中,如果NS空间进行格式化的时候开启了端到端的数据保护功能:
- Guard检查:如果PRCHK(PI Check)中的Guard Check bit为1,则Controller在需要将接收到的Guard字段,与基于接收到的数据计算生成的Guard进行比较,一致,则校验通过。
- Application Tag Check:PRCHK字段中的Application Tag Check bit用于指示控制器是否应该对PI中的Application Tag进行检查。如果设置为‘1’,则表示需要对Application Tag中未被“屏蔽”的位进行检查。“屏蔽”的意思是在比较过程中需要控制器忽略的某些位,不需要进行比较,这些位可以通过命令中的LBATM(Logical Block Application Tag Mask,逻辑块应用标签掩码)字段或者ELBATM(Expected Logical Block Application Tag Mask,期望的逻辑块应用标签掩码)字段来控制。
- Storage Tag Check:如果PI中包含了Storage Tag且Storage Tag Check位被设置为‘1’,那么NVM控制器将会比较Storage Tag字段中的未屏蔽位和命令中的LBST(Logical Block Storage Tag,逻辑块存储标签)字段。与Application Tag类似,Storage Tag中的某些位也可以被"屏蔽",无需NVM控制器检查,方法是通过将LBSTM(Logical Block Storage Tag Mask,存储标签掩码)字段中的相应位清除为‘0’即可。
- Reference Tag Check:如果Reference Tag被定义,且PRCHK中的Reference Tag检查位为1,
- NS被格式化为Type 1或Type 2时:控制器需要将Reference Tag和依据PI Type计算出来的Reference Tag进行比较。
- Type 1保护时,计算出来的第一个Reference Tag应和ILBRT或EILBRT保持一致,且和SLBA字段的最低有效位的4个字节相同,后续逻辑块数据计算得出的Reference Tag应依次递增。需要注意,NVMe 2.0提出Reference Tag可以少于4个字节,此时只需要保证相应比特数的值相同即可。
- Type 2保护时,基于第一个逻辑块数据计算得出的Reference Tag应和ILBRT或EILBRT相同,并且对于每个后续的逻辑块数据,计算出的Reference Tag应依次递增。
- Type 3时:Controller只需要计算出Reference Tag,但不需要和PI中原有的Reference Tag进行比较,也就是说,即使二者不一致,也不会将其视为错误而中止命令。同时,控制器可以直接忽略ILBRT和EILBRT字段,不进行检查。但如果IO Write命令居然将PRCHK中的Reference Tag Check设置为1,那么命令将以“Invalid Protection Information”或“Invalid Field in Command”状态码中止。
- 对于计算出来的Reference Tag,当所有位都为1时,则下一个递增标签可以从全“0”开始。
- NS被格式化为Type 1或Type 2时:控制器需要将Reference Tag和依据PI Type计算出来的Reference Tag进行比较。
比如下面这笔IO写(4K+8)命令中LBST、ILBRT与每笔Metadata中的Storage Tag、Reference Tag关系如下,也基于此来进行校验。
┌───────────────────┐
│ 物理页 0 │
├─────────┬─────────┤
│ UserData│ Metadata│
│ (4KB) │ (8B PI) │
┌────────────►├ ─ ─ ─ ─ ┼─────────┤
│ │ │ ST=0xAA │ ← 来自SQE.LBST
写入NAND │ │ │ RT[0..7]│
│ │ │ =0x1000 │
│ │ │ ... │ ← 自动生成8个递增的RefTag
│ │ │ =0x1007 │
│ └─────────┴─────────┘
┌───────────────┐│ ┌───────────────────┐
│ 主机8KB数据 ├┤ │ 物理页 1 │
│ + 初始标签 ││ ├─────────┬─────────┤
│ (LBA X~X+15) ││ │ UserData│ Metadata│
│ LBST=0xAA │└────────────►├ ─ ─ ─ ─ ┼─────────┤
│ ILBRT=0x1000 │ │ │ ST=0xAB │ ← LBST+1 (页偏移)
└───────────────┘ │ │ RT[0..7]│
│ │ =0x1008 │ ← 续接前页的RefTag序列
│ │ ... │
│ │ =0x100F │
└─────────┴─────────┘

1594

被折叠的 条评论
为什么被折叠?



