就在前不久,我们发布了全新一代PCIe 5.0企业级NVMe SSD——PBlaze7 7940。与上一代PCIe 4.0产品相比,其综合性能有着超过100%的提升,增添了很多新的功能以满足企业级客户多样化的产品需求。其中一项新的功能便是我们今天谈论的主角——Get LBA Status,即“逻辑块地址状态获取”,它可以让Host主动感知已经失效的LBA地址并做出应对,降低数据彻底损坏的风险和对业务造成的影响。
在正式进入话题前,我们需要进行一些背景介绍,以便更好地让读者理解这个功能,熟悉的读者可以直接跳过这部分。
背景介绍:L2P与坏块
对SSD来说,通常会有逻辑块地址(LBA,Logical Block Address)和物理块地址(PBA,Physical Block Address)相互映射的概念,把NAND 介质PBA抽象为上层Host端应用按照统一的LBA访问规则去使用。它可以根据实际需要非对称地对LBA和PBA进行映射,生成逻辑与物理地址映射关系表(L2P Table)来进行管理,如下图所示:
坏块(BB,Bad Block),不管是在HDD时代(类似的概念为坏道)还是SSD时代都被用户所厌恶的东西,一直也都是存储设备数据保护机制中需要重点维护管理的对象之一。存储介质的物理块会因为很多原因(如生产工艺限制、使用中失效等)导致无法使用,成为一个物理坏块,进而影响到与之映射的逻辑块,需要SSD在后台重新进行映射等工作,如,断开坏块所在的PBA-x与LBA-x的映射关系,从超额配置预留空间(OP,Over-Provisioning Space)中选取适合的PBA-y替换回去。
为什么要关注LBA的状态?
Get LBA Status是NVMe协议中的一个可选功能,它的作用简单来讲,就是让Host端可以定期、及时地获知当前使用中的LBA状态好坏,在应用层面来进行一些潜在失效LBA中的数据备份与恢复工作,避免Host端应用再去使用那些不可靠的LBA。
细心的读者可能会问了,既然它是可选功能,说明传统实现方案中,Host对于LBA失效管理存在另一种方式?
是的,在不支持此功能的实现中,SSD固件会在后台主动地去管理PBA中的坏块信息,整理为一张Bad Block Table,保证L2P Table中的映射关系都是可靠有效的。但假如某一个LBA对应的PBA已经存有有效的用户数据,在Host访问期间该PBA变为坏块,SSD需立即调用一系列数据恢复操作,如调整NAND读电压、BCH、LDPC纠错算法,甚至Die间Raid5软阵列保护机制等,以便将完整的数据读取出来,并造成延迟的增加。
Get LBA Status赋予了Host更加积极主动的方式来提前获知LBA的潜在失效情况,以方便Host做好后续LBA操作规划,并提前进行一些应用层面的数据备份与恢复工作。其具体协议规范和实现逻辑,我们来仔细解读一下最新的NVMe 2.0协议中对应的内容吧!
协议规范要求解析
Get LBA Status:Potentially Unrecoverable LBAs are LBAs that, when read, may result in the command that caused the media to be read being aborted with a status code of Unrecovered Read Error. The Get LBA Status capability provides the host with the ability to identify Potentially Unrecoverable LBAs. The logical block data is able to be recovered from another location and re-written.
潜在的不可恢复的LBA是指在读取时可能导致读取命令中止,状态为Unrecovered Read Error的LBA。“Get LBA Status”功能为主机提供了识别潜在不可恢复的LBA的能力。逻辑块数据可以从另一个位置恢复并重新写入。
这里描述的Potentially Unrecoverable LBAs就是我们前面所指的潜在失效(不可恢复)逻辑块地址。Get LBA Status的意义,就是尽量提前让Host知道这样的LBA,早治疗!
要想支持Get LBA Status功能,需要SSD满足以下这些条件:
- indicate support for the Get LBA Status capability in the Optional Admin Command Support (OACS) field in the Identify Controller data structure;
- indicate support for LBA Status Information Alert Notices in the Optional Asynchronous Events Supported (OAES) field in the Identify Controller data structure;
- support the LBA Status Information log page;
- indicate support for the Log Page Offset and extended Number of Dwords (i.e., 32 bits rather than 12 bits) in the Log Page Attributes field of the Identify Controller data structure;
- support the LBA Status Information Attributes Feature;
- support the Get LBA Status command; and
- support the LBA Status Information Alert Notices event.
内容较多,我们来一条条梳理:
在Identify Controller data structure(Controller用于向Host说明自身能力的一个数据结构)的Optional Admin Command Support(OACS,可选管理命令支持)字段中需体现出对Get LBA Status的支持。
在Identify Controller data structure的Optional Asynchronous Events Supported(OAES,可选异步事件支持)字段中,需体现出对LBA Status Information Alert Notices(逻辑块地址状态信息警告通知)的支持。
支持LBA Status Information log page(逻辑块地址状态信息日志页),日志是NVMe协议中一种很重要的设备状态信息载体,通过发送Get Log Page命令并附上当前想要获取的日志页ID,即可获取对应的日志信息。
在本文中,LBA Status Information log page ID为0Eh。它的主要作用是当LBA Status Information Alert 触发向Host端发出AEN(Async Event Notice)警告,Host端收到了这项警告,并通过向Controller申请获取LBA Status Information log page,来了解对应NS上大致的潜在失效LBA地址范围,以供后续Get LBA Status命令的具体探测及一系列相关的处理动作。
在NVMe协议中,会有很多Feature用来获知和设置对应的功能属性,通过Get Feature/Set Feature命令操作来交互。LBA Status Information Attributes的Feature ID是15h,定义如下图所示。它设置的属性主要是用于控制每次Host获取/Controller发送LBA Status Information Log的最短时间间隔。
支持Get LBA Status Command,即本文的主角。当OACS字段表示支持本命令后,通过发送它,根据不同的命令设定参数,Host可以获知当下所有的Tracked(已追踪) LBAs以及Untracked(未追踪) LBAs。
a) Tracked LBAs一般是FW后台已经通过定期扫描或者读写操作时发现并内部记录的Bad Block对应的LBAs,获取它们的信息是直接的,几乎没有延迟开销;
b) Untracked LBAs是指需要通过Controller在收到命令时主动做一些扫描动作,以确定哪些LBAs是潜在不可恢复的LBAs,控制器可以使用此扫描来确定哪些名称空间中的哪些LBAs受到组件(例如die或channel)故障的影响,并根据实际情况决定是否把它们归入Tracked LBA List。需要注意的是,这种扫描操作会导致较为明显的延迟。
Get LBA Status Command具体的定义见下图。
支持LBA Status Information Alert Notice Event,它属于Asynchronous Event中Notice Event Type的一种,它在Asynchronous Event Request命令完成返回值中,对应的Asynchronous Event Information值为05h。Asynchronous Event Request命令由Host提出,并可以在限制数量内提出多条同时挂起在后台。这个命令没有返回超时的限制,可以一直挂着,直到有事件发生,Controller才会根据对应事件的各种类型发送一个返回值,作为对一条挂起命令的回应。下图非完整表格,我们需关注的只有LBA Status Information Alert。
当OAES字段表示支持本事件后,每当事件对应的条件被触发,并且后台有Host发出并还挂起着的Asynchronous Event Request命令,Controller就会回应LBA Status Information Alert Notice Event,拉响警报要求Host来进行后续操作。具体的逻辑流程,我们下一个板块继续讨论。
功能实现流程逻辑梳理
接下来,我们盘一盘它的逻辑路线。首先根据NVMe协议,我们需要用Get/Set Feature Command去设置以下这两个Feature:
a) LBA Status Information Attributes Feature。Host有两种方式可以获取LBA Status Information Log Page,一种是Poll,以轮询方式不停地向Controller要求Log Page,此时Get Log 命令中Retain Asynchronous Event bit(保留异步事件比特位)需要保持为“0”,且不Enable LBA Status Information Notices这个功能,因此这种方式不是本文操作所选择的。另一种是作为处理LBA Status Information Alert Notice Event的后续流程,来按照协议设定的规则读取LBA Status Information Log Page。
因此,LBA Status Information Poll Interval(LSIPI,逻辑块地址状态信息轮询间隔)是指Host在每次主动向Controller轮询LBA Status Information Log Page时,应当等待的最短时间间隔(以间隔数量表示,每单位数量代表100ms),此值由Controller设定,Host无法更改。而LBA Status Information Report Interval(LSIRI,逻辑块地址状态信息报告间隔)是指Controller每次要上报LBA Status Information Alert Notice Event之前,应该等待的最短延迟时间,此值可由Host设定。
需要注意的是,当LBA Status Information Notices被Enable时,LSIRI的默认值会与LSIPI相等。当Host想自定义LSIRI时,必须保证它的值不小于LSIPI,否则Controller不会采纳这个无效值,并且在Set Feature的返回值中告知Host它能支持的最接近无效值的LSIRI。
b) LBA Status Information Notices通过Asynchronous Event Configuration(异步事件配置)这个Feature控制,下图只列出了与本文相关的Bit13,通过这个Bit控制是否Enable LBA Status Information Notices。当Enable时,每当警告出现,Controller会通知Host事件发生,反之则不通知。
其次,当LBA Status Information Alert Notices被Enable后,当下述其中一个条件被满足时,Controller才会向Host发送LBA Status Information Alert Notice Event:
a) 存在Tracked LBAs并且:当前LSIRI的时间间隔条件已满足,或者若有自定义实现中特定的Tracked LBAs总阈值存在并且被超过。
b) 出现可能导致Controller 中止命令并且回报Unrecovered Read Error(URE,不可恢复的读取错误)状态码的元件(例如存储介质芯片,数据信道等)失效/故障事件。
第三,Host收到LBA Status Information Alert Notice Event后,需要遵循下述说明的规则来交互,获取LBA Status Information Log Page:
a) 当收到LBA Status Information Alert Notice Event时,Host应当根据实际情况发送一个或多个Get Log Page命令来获取Log ID为0Eh的LBA Status Information Log Page,将Retain Asynchronous Event Bit置为“1”来表示当次Event相关的Log Page读取操作还在继续中。当Retain Asynchronous Event Bit置“1”时,Controller不能对当前的Log Page进行改动,哪怕有需要更新的Log部分,直到Bit置为“0”。
b) 当Host发来的Get Log Page命令中,Retain Asynchronous Event Bit置“0”时,代表Host对应此次Event的Log Read已经完成,后台处于挂起状态中的LBA Status Information Alert Notice Event会被清除,并且Controller会重新开始对LSIRI时间间隔进行计时。
c) 考虑到Host读取Log Page时,Controller可能会有想更新的Log Page需要上报,它会把这个需求体现在Host本轮的最后一次Get Log Page命令中(Retain Asynchronous Event Bit置“0”)的LBA Status Generation Counter(逻辑块地址状态生成计数器)字段,通过增加这个计数值表示当前Log Page有更新。Host在读取最后一次Log Page时会比对这个计数是否和本轮之前的计数一致。如果不一致,说明又有新的Log Page已经准备好了,此时Host可以忽视LSIPI的间隔时间限制主动重新Poll Log Page。
至此,关于Get LBA Status功能的绝大部分知识点已经介绍完了,相信读者们对于这个功能有了更清晰的认知。作为一个可选功能,在企业级SSD产品中要想实现它,需要满足上述的诸多要求,在此也感谢所有在产品开发中付出大量努力的工程师们
本次的全新一代PBlaze7 7940系列PCIe 5.0企业级NVMe SSD首次实现了这个功能,为Host数据保护工作提供了主动巡查的机制,更多地保障了企业用户在使用忆恒创源产品时的数据安全需求,为用户业务保驾护航!