【NVMe2.0b 12】NVM 容量模型

本文详细解读了NVM容量模型,涉及MediaUnit的组织示例,如单域、垂直和横向组织的NVM子系统,以及容量报告的流程,包括EnduranceGroups、NVMSets和命名空间的容量分配。了解这些有助于优化NVM资源管理和性能目标设定。

3.8NVM容量模型

3.8.1概述

NVM 子系统可以报告 NVM 子系统内多个实体的容量相关信息。此容量报告模型包括 NVM subsystem、域(Domain,请参阅第 3.2.4 节)、耐力组(Endurance Group,请参阅第 3.2.3 节)、NVM Set(请参阅第 3.2.2 节)、命名空间(namespace,请参阅第 3.2.1 节)和媒体单元(Media Unit,参阅第 1.5.34 节)。NVM 子系统可能支持部分、全部或不支持此类报告。

Figure 12 显示了 NVM 子系统中用于管理 NVM 容量的实体的层次关系。

NVM Set 中的容量可以分配给一个或多个命名空间,并且每个命名空间完全存在于该 NVM Set 中(请参阅第 3.2.2 节)。并非 NVM Set 中的所有容量都需要分配给命名空间。

如果控制器支持 NVM Set,则 Endurance Group 中的容量可以分配给一个或多个 NVM Set,并且每个 NVM Set 完全存在于该 Endurance Group 中(请参阅第 3.2.3 节)。并非 Endurance Group 中的所有容量都需要分配给 NVM Set。

如果控制器支持 Endurance Groups 并且不指示支持 NVM Set,则在所有包含 NVMSETID 字段的数据结构中,NVMSETID 字段应清除为 0h。

如果控制器不支持 Endurance Groups,则在所有包含 ENDGID 字段的数据结构中,ENDGID 字段应清除为 0h。

如果控制器支持 Endurance Groups,则域中的容量可以分配给一个或多个 Endurance Groups,并且每个 Endurance Group 完全存在于该域中(请参阅第 3.2.4 节)。并非域中的所有容量都需要分配给Endurance Group。

NVM 子系统可以根据 Media Units 报告 Endurance Groups 和 NVM Set 的组成。每个Media Units都被分配给一个 Endurance Group。如果支持 NVM Set,则每个 Media Unit 都被分配给一个 NVM Set。数据通过 Channels 传入和传出 Media Units。每个 Media Units 都连接到一个或多个 Channels。每个Channel 都连接到一个或多个 Media Units。

主机使用 Capacity Management(参见第 8.3 节)来分配:

  1. Domain 的容量给 Endurance Groups;
  2. Endurance Group 的容量给 NVM Sets;
  3. Media Units 给 Endurance Groups; and
  4. Media Units 给NVM Sets,

作为创建这些实体的一部分。

主机使用 Namespace Management (请参阅第 8.11 节)为命名空间分配容量。

3.8.2Media Unit的组织示例

Media Units的分配用于组织 NVM 子系统中的物理 NVM 资源以满足特定的performance目标。 以下示例显示了一个 NVM 子系统,其中包含单个域中的所有资源。该域有四个Channels,每个Channel都有四个 Media Units。

3.8.2.1简单的NVM子系统

Figure 104 显示了一个单域 NVM 子系统的示例,其中跨所有媒体单元管理 endurance。

performance目标是最大带宽,这是通过允许每个read或write操作同时访问所有 Media Units 来实现的。所有 Media Units 都在同一个 Endurance Group 和同一个 NVM Set中。

Figure 104: Simple NVM Subsystem

在这里插入图片描述

此示例的 Capacity Configuration Descriptor 包含一个 Endurance Group Configuration Descriptor。Endurance Group Configuration Descriptor 包含一个 NVM Set Identifier 和四个 Channel Configuration Descriptors。每个 Channel Configuration Descriptor 包含四个 Media Unit Configuration Descriptors。 3.8.2.2垂直组织的NVM子系统

Figure 105 显示了单域 NVM 子系统的示例,其中performance目标是以带宽为代价在四个 NVM Sets之间进行隔离。Endurance 为每组单独管理。共享一个Channel的 Media Units 被分配到同一个Endurance Group。Endurance Group 中的所有 Media Units 都分配给同一个 NVM Set。任何 NVM Set 的带宽都可能小于或等于该 NVM Set的 Channel 带宽。

Figure 105: Vertically-Organized NVM Subsystem

在这里插入图片描述

此示例的 Capacity Configuration Descriptor 包含四个 Endurance Group Configuration Descriptors。每个 Endurance Group Configuration Descriptor 包含一个 NVM Set Identifier 和一个 Channel Configuration Descriptor。每个 Channel Configuration Descriptor 包含四个 Media Unit Configuration Descriptors。

3.8.2.3横向组织的双NAND NVM子系统

Figure 106 显示了单域 NVM 子系统的示例,其中 Media Units 是能够作为 QLC 或以较低密度运行的 NAND。Performance 目标是为作为 SLC 运行的小 NVM Set 和作为 QLC 运行的较大 NVM Set 提供最大带宽。

Figure 106: Horizontally-Organized Dual NAND NVM Subsystem

在这里插入图片描述

Capacity Configuration Descriptor 将包含两个 Endurance Group Configuration Descriptors。此示例的第一个 Endurance Group Configuration Descriptor:

  • 表示 Capacity Adjustment Factor 约为 1,600;
  • 包含一个 NVM Set Identifier;
  • 包含四个 Channel Configuration Descriptors。每个 Channel Configuration Descriptor 包含一个 Media Unit Configuration Descriptor。

此示例的第二个 Endurance Group Configuration Descriptor:

  • 表示 Capacity Adjustment Factor 为 100;
  • 包含一个 NVM Set Identifier;
  • 包含四个 Channel Configuration Descriptors。每个 Channel Configuration Descriptor 包含三个 Media Unit Configuration Descriptors。

3.8.3容量报告

对于不支持多个域的 NVM 子系统,Identify Controller data structure 中报告的容量信息(即Figure 275 中的 TNVMCAP 字段和 UNVMCAP 字段)描述了 NVM 子系统的容量。如果 MEGCAP 字段不为0,则该字段表示可以在 NVM 子系统中创建的最大实体(例如,Endurance Group、NVM Set、namespace)。

对于支持多个域的 NVM 子系统,Identify Controller data structure 中报告的容量信息描述了处理Identify命令的控制器可访问的容量。主机可以使用Identify命令访问 Domain List data structure(请参阅第 5.17.2.17 节)以确定控制器可访问的域以及每个域的容量信息。如果 Max Endurance Group Domain Capacity 字段不为0,则该字段描述了可由该控制器在该 Domain Attributes Entry 描述的域中创建的最大实体(例如,Endurance Group、namespace)。

对于支持 Endurance Groups 的 NVM 子系统(请参阅第 3.2.3 节),主机可以使用 Identify 命令访问 Endurance Group List data structure(请参阅第 5.17.2.18 节)以确定可由控制器访问的Endurance Groups。要确定每个 Endurance Group 的容量信息,主机使用 Get Log Page 命令访问 Endurance Group Information log page(请参阅第 5.16.1.10 节)。

对于支持 NVM Set 的 NVM 子系统(请参阅第 3.2.2 节),主机可以使用识别命令访问 NVM Set 列表数据结构(请参阅第 5.17.2.4 节)以确定主机可以访问的 NVM Set 控制器和每个 NVM Set 的容量信息。

对于 Endurance Groups、NVM Sets 和命名空间的管理,Figure 107 描述了支持 NVM Sets、Endurance Groups 和 Domains 的效果,在这些域上,容量信息用于每个管理操作。

Figure 107: Capacity Information Field Usage

在这里插入图片描述

### NVMe 2.0c 版本 PRP 使用方法 在 NVMe 协议中,PRP (Physical Region Page) 是一种内存映射机制,用于描述数据缓冲区的位置。它允许主机和设备之间高效地传递大块数据,而无需复杂的 DMA 映射操作。 #### PRP 结构概述 PRP 主要分为两种形式:单页 PRP 和双页 PRP。具体使用方式取决于数据传输的大小和位置: 1. **单页 PRP**: 当数据完全位于一个连续的页面内时,可以使用单页 PRP 来指定该页面的地址。 2. **双页 PRP**: 如果数据跨越两个连续页面,则需要提供两个 PRP 地址(`PRP Entry 1` 和 `PRP Entry 2`),分别指向这两个页面的起始地址。 对于更大的数据传输需求,可以通过链表的方式扩展 PRP 列表[^5]。 #### NVMe 2.0c 中 PRP 的使用场景 在 NVMe 2.0c 规范中,PRP 的使用保持了向后兼容性,同时引入了一些新的特性来优化性能和灵活性。以下是其主要应用场景: 1. **Admin 命令中的 PRP** - Admin 命令通常涉及配置和管理操作,可能不需要大量数据传输。但在某些情况下(如 Firmware Download 或 Format NVM),仍需使用 PRP 描述数据缓冲区。 - 这些命令会通过 `Command Dword 0` 定义具体的参数布局,并利用 `PRP Entry 1` 和 `PRP Entry 2` 指定数据区域[^5]。 2. **I/O 命令中的 PRP** - I/O 命令主要用于读取和写入命名空间的数据。在这种情况下,PRP 被广泛应用于描述主机与存储设备之间的数据交换。 - 数据长度小于等于 4KB 时,可以直接使用单页 PRP;超过 4KB 时则需要构建 PRP 链表以覆盖整个数据范围。 3. **SGL 替代方案** - 在一些高级用例中,可以选择 Scatter-Gather List (SGL) 取代传统的 PRP 方案。这使得更复杂的数据分布能够被有效支持,尤其是在非连续内存分配的情况下[^5]。 #### 示例代码展示 PRP 构建逻辑 以下是一个简单的 Python 实现示例,演示如何为 NVMe 写入命令准备 PRP 表项: ```python def build_prp(data_buffer, page_size=4096): """ 构造 NVMe PRP 表项 :param data_buffer: 数据缓冲区列表,每个元素表示一页数据的起始地址 :param page_size: 页面大小,默认为 4KB :return: 返回 PRP Entry 1 和 PRP Entry 2 组成的元组 """ total_length = sum(len(buf) for buf in data_buffer) if total_length <= page_size: # 单页 PRP return (data_buffer[0], None) elif total_length <= 2 * page_size: # 双页 PRP return (data_buffer[0], data_buffer[1]) else: raise ValueError("Data exceeds two pages; consider using an SGL instead.") # 示例调用 buffer_page_1 = 0x1000 # 第一页地址 buffer_page_2 = 0x2000 # 第二页地址 prp_entries = build_prp([buffer_page_1, buffer_page_2]) print(f"PRP Entry 1: {hex(prp_entries[0])}") if prp_entries[1]: print(f"PRP Entry 2: {hex(prp_entries[1])}") ``` 此函数可以根据输入的数据缓冲区自动决定采用哪种类型的 PRP,并返回对应的表项值。 --- ### 注意事项 尽管 NVMe 2.0c 提供了许多增强功能,但实际应用中需要注意以下几点: - 不同硬件平台对齐要求可能存在差异,请参照具体控制器文档确认细节[^5]。 - 若目标环境支持 SGL 功能,在处理大规模随机访问任务时建议优先考虑 SGL 方法以简化编程模型并提升效率[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值