NVMe协议之NVM Command简介

  NVM Command是NVMe协议里面的IO命令,主要包含Write、Read、Compare、Verify、Write Zeroes、Write Uncorrectable、Reservation这些命令。命令下发需满足以下两点:控制器状态寄存器(CSTS.RDY);创建了适当的I/O SQ和CQ。

检查当前磁盘支持哪些NVM Command

  我们知道并不是所有NVM Command盘片都支持,在协议里只规定Flush、Write、Read命令是强制要求的,其他的都是可选项。所有我们在使用时,需要查看一下命令是否支持。可以通过查看Identify Controller Data Structure的ONCS[521:520]查看命令是否支持。

Bit 7:如果置1,则主控支持Verify命令;否则不支持;
Bit 5:如果置1,则主控支持Reservations;否则不支持;
Bit 3:如果置1,则主控支持Write Zeroes;否则不支持;
Bit 2:如果置1,则主控支持Dataset Management;否则不支持;
Bit 1:如果置1,则主控支持Write Uncorrectable;否则不支持;
Bit 0:如果置1,则主控支持Compare命令;否则不支持;

NVM Command详解

注:命令下发使用nvme-cli做演示。
  一、Flush命令
  用于请求使易失性写缓存的内容的内容具有非易失性,即Flush命令应将与指定命名空间相关联的数据和元数据提交给非易失性介质。Flush命令适用于控制器在提交flush命令之前完成的指定名称空间的所有命令。控制器还可以从任何名称空间中刷新其他数据和元数据。
  我们还可通过Idnetify controller Data Structure的VWC[525]查看盘片是否存在易失性写缓存。

Bit 0:如果置1,表示存在易失性写缓存;否则不存在;
Bit 2:1:表示NSID设置FFFF FFFFh时,指示Flush命令行为。
00b:表示不支持将NSID设为FFFF FFFFh,只有在1.3之前版本才支持返回此值
01b:保留字段
10b:表示Flush不支持将NSID设为FFFF FFFFh,返回状态码为Invalid Namespace or Format
11b:表示Flush支持将NSID设为FFFF FFFFh

注:若不存在易失性写缓存或者未启用,则flush命令也可以成功完成,只是没有效果。

#不指定namespace
> nvme flush /dev/nvme0n1
#指定namespace下发flush命令
> nvme flush -n 1/2... /dev/nvme0n1

  二、Reservation命令
  该命令用于namespace上的权限管理操作。消费级盘该指令不常见,故不作过多介绍。

Reservation Acquire命令:用于获取名称空间上的预订,抢占名称空间上的预订,以及中止名称空间上保持的预订
Reservation Register命令:用于注册、注销或替换保留密钥
Reservation Release命令:用于释放或清除保留在命名空间上的预订
Reservation Report命令:将Reservation Status数据结构返回到内存,该数据结构描述命名空间的注册和预订状态

  三、Write命令
  会将数据和元数据写入所指示的逻辑块的I/O控制器,主机还可以指定保护信息作为操作的一部分。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[31] --limited-retry,-l 进行有限次retry用于错误恢复
CDW12[30] --force-unit-access,-f 强制设备在命令完成之前将数据写到闪存,数据还是会经过缓存进行写入,只是会等待写入闪存后才返回命令
CDW12[29:26] --prinfo,-p 指定保护信息操作和检查字段
CDW12[23:20] --dir-type,-T 指令类型,可在identify[257:256]Bit 5查看支持情况
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based
CDW13[31:16] --dir-spec,-S 指定与‘DTYPE’字段相关的指令特定值
CDW13[07:00] --dsm,-D 表示正在写的LBA的属性
CDW14[31:00] --ref-tag,-r 指定初始逻辑块参考标记值,把逻辑块数据与一个地址关联起来,防止被误用或者乱序逻辑块传输,用来检测数据是否写入错误的LBA。prinfo使用才用此值
CDW15[31:16] --app-tag,-a 指定应用程序标记值,prinfo使用才用此值
CDW15[15:00] --app-tag-mask,-m 指定应用程序标记掩码值,prinfo使用才用此值
DATA Pointer[63:00] --data-size,-z 指定传输的数据
Metadata Pointer[127:00] --metadata-size,-y 指定元数据指针

  write命令下发,下面命令执行效果相同。

> echo "7788" | nvme write -s 0 -c 1 -z 512 /dev/nvme0n1
Rounding data size to fit block count(1024 bytes)
write:Success
> cat data.bin
7788
> nvme write -s 0 -c 1 -z 512 -d data.bin /dev/nvme0n1
Rounding data size to fit block count(1024 bytes)
write:Success

  四、Read命令
  会从所指示的lba的I/O控制器中读取数据和元数据,该命令可以指定作为读取操作的一部分所要检查的保护信息。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[31] --limited-retry,-l 进行有限次retry用于错误恢复
CDW12[30] --force-unit-access,-f 强制设备在命令完成之前将数据写到闪存,数据还是会经过缓存进行写入,只是会等待写入闪存后才返回命令
CDW12[29:26] --prinfo,-p 指定保护信息操作和检查字段
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based
CDW13[07:00] --dsm,-D 表示正在写的LBA的属性
CDW14[31:00] --ref-tag,-r 指定初始逻辑块参考标记的期望值,prinfo使用才用此值
CDW15[31:16] --app-tag,-a 指定应用程序标记的期望值,prinfo使用才用此值
CDW15[15:00] --app-tag-mask,-m 指定应用程序标记掩码的期望值,prinfo使用才用此值
DATA Pointer[63:00] --data-size,-z 指定读取的数据大小
Metadata Pointer[127:00] --metadata-size,-y 指定元数据指针

  read命令下发,下面命令执行效果相同。

> nvme read -s 0 -c 1 -z 512 /dev/nvme0n1
Rounding data size to fit block count(1024 bytes)
7788
read:Success
> nvme read -s 0 -c 1 -z 512 -d data.bin /dev/nvme0n1
Rounding data size to fit block count(1024 bytes)
read:Success
> cat data.bin
7788

  五、Write Uncorrectable命令
  用于将一系列逻辑块标记为无效。在此操作之后读取指定的逻辑块时,返回未恢复读取错误状态[02,81]。要清除无效的逻辑块状态,需要对这些逻辑块执行写入操作。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based

  write uncorrectable命令下发。

> nvme write-uncor -n 1 -s 0 -c 2 /dev/nvme0n1
NVMe Write Uncorrectable Success
> nvme read -s 0 -c 1 -z 512 /dev/nvme0n1
NVMe status:READ_ERROR:The read data could not be recovered from the media(0x281)

  六、Compare命令
  从介质中读取由该命令指定的逻辑块,并将读取的数据与作为该命令的一部分传输的比较数据缓冲区进行比较。若从控制器和比较数据缓冲区相等,没有错误,则命令成功完成;否则失败。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[31] --limited-retry,-l 进行有限次retry用于错误恢复
CDW12[30] --force-unit-access,-f 强制设备在命令完成之前将数据写到闪存,数据还是会经过缓存进行写入,只是会等待写入闪存后才返回命令
CDW12[29:26] --prinfo,-p 指定保护信息操作和检查字段
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based
CDW14[31:00] --ref-tag,-r 指定初始逻辑块参考标记的期望值,prinfo使用才用此值
CDW15[31:16] --app-tag,-a 指定应用程序标记的期望值,prinfo使用才用此值
CDW15[15:00] --app-tag-mask,-m 指定应用程序标记掩码的期望值,prinfo使用才用此值

  compare命令下发。

> nvme compare -s 0 -c 1 -z 512 -d data.bin /dev/nvme0n1
Rounding data size to fit block count(1024 bytes)
compare:Success

  七、Write Zeroes命令
  用于将逻辑块的范围设置为零,成功完成此命令后,后续读取此范围内的逻辑块返回的值应清除到0h,直到写入此LBA范围。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[31] --limited-retry,-l 进行有限次retry用于错误恢复
CDW12[30] --force-unit-access,-f 强制设备在命令完成之前将数据写到闪存,数据还是会经过缓存进行写入,只是会等待写入闪存后才返回命令
CDW12[29:26] --prinfo,-p 指定保护信息操作和检查字段
CDW12[25] --deac,-d 主机是否解除分配的指定逻辑块,即同trim返回值相同
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based
CDW14[31:00] --ref-tag,-r 指定初始逻辑块参考标记值,把逻辑块数据与一个地址关联起来,防止被误用或者乱序逻辑块传输,用来检测数据是否写入错误的LBA。prinfo使用才用此值
CDW15[31:16] --app-tag,-a 指定应用程序标记值,prinfo使用才用此值
CDW15[15:00] --app-tag-mask,-m 指定应用程序标记掩码值,prinfo使用才用此值

  write zeroes命令下发。

> nvme write-zeroes -n 1 -s 0 -c 2 /dev/nvme0n1
NVMe Write Zeroes Success

  八、Verify命令
  通过读取指示的LBA的数据和元数据(如果适用)来验证存储信息的完整性,而不向主机传输任何数据或元数据,Verify操作包括在执行Verify命令期间验证存储信息完整性的控制器操作(例如读取)。即verify本身不传输数据,就是内部读一下看看能不能读,能读就通过。出unc时会报错,即unrecovered read error[02.81]。

协议 Nvme-cli 释义
CDW10&11[63:00] --start-block,-s 开始的逻辑块地址
CDW12[31] --limited-retry,-l 进行有限次retry用于错误恢复
CDW12[30] --force-unit-access,-f 强制设备在命令完成之前将数据写到闪存,数据还是会经过缓存进行写入,只是会等待写入闪存后才返回命令
CDW12[29:26] --prinfo,-p 指定保护信息操作和检查字段
CDW12[15:00] --block-count,-c 表示要写入的逻辑块数,基于0‘s based
CDW14[31:00] --ref-tag,-r 指定初始逻辑块参考标记的期望值,把逻辑块数据与一个地址关联起来,防止被误用或者乱序逻辑块传输,用来检测数据是否写入错误的LBA。prinfo使用才用此值
CDW15[31:16] --app-tag,-a 指定应用程序标记的期望值,prinfo使用才用此值
CDW15[15:00] --app-tag-mask,-m 指定应用程序标记掩码的期望值,prinfo使用才用此值

  write zeroes命令下发。

> nvme verify /dev/nvme0n1
NVMe Verify Success
> nvme verify -n 1 -s 0 -c 1 /dev/nvme0n1
NVMe Verify Success

  九、Dataset Management命令
  主机使用“数据集管理”命令来指示逻辑块的范围属性,包括如读或写数据的频率、访问大小及其他优化性能和可靠性的信息属性。此命令为建议性命令,控制器可以根据所提供的信息选择不采取任何操作。

协议 Nvme-cli 释义
CDW10[07:00] Range[--ctx-attrs,-a;--blocks,-b;--slbs,-s] 指定16字节范围集的数量,基于0's based
CDW11[02] --ad,-d NVM子系统可以解除分配所有提供的范围,trim
CDW11[01] --idw,-w 数据集被优化为一个集成单元的写访问,即写入数据集一部分,那么预计数据集中所有范围都将被写入
CDW11[00] --idr,-r 数据集被优化为一个集成单元的写访问,即写入数据集一部分,那么预计数据集中所有范围都将被写入

  Context Attributes
  为每个Range指定上下文属性提供了主机如何实现该范围的信息,此信息的使用是可选的,控制器不需要执行任何特定的操作。
  注:无论主机提供属性是否准确,控制器都需要保持NVM介质上数据的完整性。

Command Access Size[31:24]:此数据集的单个读或写命令中预期传输的逻辑块数;置0,表示未提供访问大小
WP,Write Prepare[10]:置1,则所提供的范围预计将在不久将来被写
SW,Sequential Write Range[09]:置1,则数据集应针对顺序写访问进行优化;主机希望将数据集做为单个对象进行写入操作
SR,Sequential Read Range[08]:置1,则数据集应针对顺序读访问进行优化;主机希望将数据集做为单个对象进行读取操作
AL,Access Latency[05:04]:
    00b:None
    01b:Idle,可接受更长时间延迟
    10b:Normal,典型的延迟
    11b:Low,最小可能的延迟
AF,Access Frequency[03:00]:
    0h:不提供任何频率信息
    1h:此LBA范围典型的读写数
    2h:对指示的LBA很少写入和很少读取
    3h:对LBA范围不频繁写和频繁读
    4h:对LBA范围频繁写和不频繁读
    5h:对LBA范围频繁读取和写入

  Deallocate
  使用DSM命令释放的逻辑块在写入逻辑块时不在释放,read和verify不会影响逻辑块的释放状态;从释放的快读取的值应是确定的。
  Dataset management命令下发。

> nvme dsm -a 0 -b 8 -s 0 -d /dev/nvme0n1
NVMe DSM:Success
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容