NVMe 规范中定义了很多功能来处理资源管理和调度问题,这些功能对于保障SSD的正常运行以及高性能、可靠性和稳定性有重要意义。本篇文章由Memblaze工程师拟写,全面介绍NVMe 的Reservation的命令和实现原理。
Reservation 这个feature的意义在于提供了一整套可以让一个,两个或者更多的Hosts共同访问一个shared namespace 的机制。
下面先列举三个host访问NVMe SSD的namespace典型场景。
场景1:host A通过Controller 1和Controller 2访问一个Namespace
场景2:host A和host B分别通过Controller 1和Controller 2访问一个Namespace
场景3:host A、host B以及host C分别通过Controller 1、Controller 2和Controller 3访问一个Namespace
所有的host通过协商建立一整套权限机制,这个权限机制是希望shared namespace 能够在权限明确的条件下更好的为Host 服务。
Reservation 功能的基本操作单元是Namespace。Reservation 的命令和通过Set feature命令实现的辅助功能的命令也都是以Namespace为单元发送到SSD 上的。为了让reservation 功能更好的运行,Log、AER(Asynchronous Event Request)、 Set Feature、Identify 等多个模块中都有相应的功能支持reservation 模块。
下面会具体介绍这些reservation 的命令和相关功能。
**Reservation一共有Reservation Register, Reservation Acquire, Reservation Release, Reservation Report 四条命令。**Reservation的命令都是NVM 命令,所以这些命令都是通过I/O queue 发送给drive 的。除了Reservation Report 命令其他三条命令都通过Command dword 10 Bit 0:2 Action 域设置不同的值使一条命令可以执行相关的几个功能。
**Reservation权限就像是一个shared namespace 的管理员权限,得到reservation权限的host 对这个shared namespace 可以做任意的读写操作。**但是在成为管理员之前需要先用reservation register 命令注册成为注册人员(registrant),从而建立host 和namespace 之间的连接, 这个操作的意义相当于通过register 的key 建立起host id 和namespace 之间的register 关系。
有了这种register 的关系表明这个host 愿意按照reservation feature 的要求和大家一起对这个shared namespace (按照reservation权限)进行相应的读写操作。当然也可以通过reservation register 命令unregister 一个registrant 和replace registrant 的key。
Register 命令的IEKEY 域有一个小细节,按照1.3 以前的NVMe spec 可以把IEKEY(ignore existing key) 设置起来不需要知道当前的key 也可以unregister 和replace key。1.3 以后的NVMe spec 禁止了这种不check key 一致性 unregister 和 replace 的行为。
unregister 的时候,host 放弃了registrant 的权限,如果之前他有reservation 管理员权限,也会随着unregister 命令执行成功释放掉。 另外,Host 是通过host id 来识别的,registrant 是通过每个namespace 上的key 来识别的。 如果两个host的host id 相同就表明两个hosts 是同一个host,在同一个namespace上的权限是一样的。
每一个namespace 在一个时间点,只能有一个reservation type 也就是只有一种管理员权限,这个管理员通过reservation 的key和host id 来标识自己的唯一性。这个管理员可以独占reservation 的读写权限,也可以把这个读写权限分享给其他registrants,甚至可以把管理员的权限分享给其他registrants。
这里的读命令不是简单的read 命令而是包括 read, compare, security receive.写命令也不是简单的write 命令而是包括 write, write uncorrectable, dataset management, flush, format NVM, namespace attachment, namespace management, security send。
Reservation 的管理员权限还包括对reservation命令和其他vendor specific命令的管理,每一个命令的行为NVME spec都有明确的说明。所有reservation type 具体权限如下图:
Registrant(注册者)通过acquire reservation 命令, 把Reservation Acquire Action (RACQA)域设置成为0 就可以得到对应的namespace 管理员权限,前提是这个namespace 的reservation 权限并没有被分配,而且register key 需要验证通过。这里需要注意一个小的细节在NVME spec 1.3 之前的版本ignore existing key(IEKEY)设置为1 是有效的,表明可以忽略register key 一致性检查,也就是说即使不知道这个host 之前register key 也是可以申请reservation 权限的。1.3 版本NVMe spec IEKEY 这个域不再允许可以设置为1, 如果设置成1 这条这个命令直接报错。
Preempt 抢占这个功能是比较特别的一个功能。它可以替换不合作的reservation holder 或者是registrant,改变原来的reservation 权限,重新建立新的权限分配规则。能成功执行抢占功能的host 一定要是registrant。
preempt抢占功能是通过把Reservation Acquire 命令的Action(RACQA) 域设置成1实现的。具体的抢占行为和reservation 的type有密切关系。具体的关系列举如下:
当reservation 的type 不是 Write Exclusive - All Registrants 和Exclusive Access - All Registrants 也就是说这个namespace reservation 权限的只有一个holder 的情况下。如果preempt reservation key(PRKEY)的值等于holder 的reservation 的key, Reservation holder会被unregister,当前的reservation权限被释放,发送这个命令的registrant会根据指定的type建立新的reservation权限。
如果PRKEY非0且没有holer的key匹配,只有PRKEY匹配的registrant,则该registrant会被unregister。发送这个命令的registrant会根据指定的type建立新的reservation权限。
如果当reservation 的type 是Write Exclusive - All Registrants 和Exclusive Access - All Registrants,这种情况下reservation 的holders 是所有注册者。如果PRKEY为0,则除了发送这条命令的registrant,其余registrants都会被unregister,当前的reservation权限被释放,新的reservation权限由抢占命令决定。
如果当前并没有reservation holder,则与PRKEY值匹配的registrant会被unregister,新的reservation权限由抢占命令决定。
registrant 可以通过preempt 命令抢占自己的权限,机制也是和上面一样,registrant 可以通过这种方法可以改变reservation 权限的type和reservation 的key.
registrant 可以通过设置 reservation acquire 命令的RACAQ 域值为2 实现 (preempt and abort) 命令. Preempt and abort 命令的功能与前面说的preempt 功能非常接近,唯一不同在于在执行preempt 行为之前SSD会尽自己最大的努力尝试去 abort 这个namespace 上的其他执行的命令。
Reservation release 命令通过Reservation Release Action(RRELA)域实现两种释放reservation 权限的功能。
当RRELA 域设置成0 时,是release reservation权限也就是释放这个namespace 上面的reservation 权限,这条命令成功需要发命令的host 是reservation 的holder。
当RRELA 域设置成1时,是clear reservation 权限也就是释放这个namespace 上所有reservation 的权限和register的权限。
这里也有一个小的细节需要注意,在NVME spec 1.3 之前的版本ignore existing key(IEKEY)设置为1 是有效的,表明可以忽略register key 一致性检查,也就是说即使不知道这个host 之前register 的key 也是可以申请reservation 权限的。1.3 版本NVMe spec IEKEY 这个域不再允许可以设置为1, 如果设置成1 ,这条这个命令直接报错。
Host 可以通过reservation report 命令拿到这个namespace上所有的reservation 权限和register 权限状态以及host ID,key 。
下面是解析的一段reservation report 的buffer 供大家参考:
同样通过这个reservation report 命令大家会发现通过这个report 我们可以知道另外一个host 的host id 和相应的reservation key, 所以从这点上看,reservation 模块是为了让host 更好的分权限工作,而不能作为安全模块用。
Memblaze的PBlaze5 910/916系列NVMe SSD在实现了双端口和multiple namespaces 功能之后,又全面实现了reservation 功能, 这样每一个namespace 都可以根据存储系统里Host 的需要让每一个namespace 更加高效有效的利用起来。
更多Memblaze的技术文章,可以扫描下面二维码: