NVMe中的Copy命令你知道吗?
前段时间做过copy的相关工作,今天抽出时间来总结一下,共勉
什么是Copy命令
顾名思义,简单理解就是复制,我们可以看看官方文档是如何定义的:
The Copy command is used by the host to copy data from one or more source logical block ranges to a single consecutive destination logical block range.
其实就是将一个或者多个逻辑块中的数据复制到一个连续的逻辑块内。虽然这个功能谈起来简单,但是对于SSD来说,其实还是相对麻烦的,对于一个功能来说,它实现的方式可以有很多种,但是如何简单实现才是最重要的,花最小的代价,实现其功能。
在之前,如果需要复制数据,需要host先读出数据,然后再写入数据,这个流程相当麻烦,如下图:
现在直接就是host发送一个copy命令,SSD自己就进行复制了,然后返回done即可,如下图所示:
上文两幅图即可简单描述copy的过程。
Copy详细配置
关于配置,我们首先看下面的结构体(自己定义):
1typedef struct nvme_copy_src_range_0_s
2{
3 /* [07:00] Reserved field 0 */
4 u64 rsvd_0;
5 /* [15:08] Starting LBA */
6 u64 start_lba;
7 /* [17:16] Number of logical blocks to be copied */
8 u32 number : 16;
9 /* [19:18] Reserved field 1 */
10 u32 rsvd_1 : 16;
11 /* [23:20] Reserved field 2 */
12 u32 rsvd_2;
13 /* [27:24] Variable sized Expected Logical Block Storage Tag (ELBST)
14 and Expected Initial Logical Block Reference Tag (EILBRT) */
15 u32 elbst_eilbrt;
16 /* [29:28] Expected Logical Block Application Tag */
17 u16 elbat;
18 /* [31:30] Expected Logical Block Application Tag Mask */
19 u16 elbatm;
20} __attribute__((packed)) nvme_copy_src_range_0_t;
copy命令中共有两种source range的格式,本文只简述一种,一个source range 32个字节,看结构体定义能够快速了解其所需的数据,copy命令也是支持End-to-end Data Protection,当然本文不作重点,最重要的就是start_lba
和number
。
配置好了一个或多个src range,你会想是不是也有一个dst range,不好意思还真没有,在nvme cmd中,只需要配置Dword 10 和 Dword 11 即可,也就是Starting Destination LBA。
配置好src range,接下来再配置 nvme cmd,主要用到 cmd 中的Dword2,3,40,11,12,13,14字段
首先来看Dword2、Dword3和Dword14,指定了可变长度的Logical Block Storage Tag (LBST)以及Initial Logical Block Reference Tag (ILBRT)
Dword10和Dword11在上文提到过,一个64位的Starting Destination LBA
Dword12和Dword15是涉及数据校验的一些内容,诸如prinfo,还有配置src 是选择format0还是format1等
Dword13是指定与指令类型字段相关联的指令特定值
请注意,协议规定了copy 命令可以从一个或者多个不连续的数据逻辑地址拷贝数据,但是目标地址必须是一个连续的逻辑地址范围,并且每个源数据必须按照顺序,复制到目标的LBA。
结
今天就到这吧,copy原理很简单,最近要做的事情比较多,卷起来!
本文首发于https://mp.weixin.qq.com/s/Bo5psuf92rOXzC-iRRibLw
则移山填海之难,
终有成功之日!
——孙文