Zoned Storage-Linux Kernel Support 之 Write Ordering Control

Linux内核原本不保证块I/O请求的执行顺序,但为了解决ZBD兼容应用的写入顺序问题,引入了zone write locking。区域写锁定在块I/O调度程序级别实现,以序列化同一区域的写入请求,确保写入顺序。最初的实现依赖于SCSI层,而改进的实现则在block I/O调度程序中,支持块多队列I/O路径,提高性能并降低写入命令饥饿的风险。

Write Ordering Control

从历史上看,Linux® 内核块 I/O 堆栈(即块层和 SCSI 层)从未保证块 I/O 请求的确切执行顺序。 由于块 I/O 请求在内核中执行的异步asynchronous性质以及设备请求队列的细粒度fine-granularity锁模型的必要性(以最小化锁- 多个上下文同时向块设备发出 I/O 请求时的争用开销)。

这种设计的直接结果是无法保证行为良好的 ZBD 兼容应用程序的写入命令将以递增的 LBA 顺序交付(匹配区域顺序写入约束)。
传入的LBA请求时间和空间上都是随机的,因此不适于ZNS的顺序写入规则

为了解决这个问题,内核 ZBD 支持添加了 zone write locking 区域写入锁定,以确保每个区域按顺序处理写入请求。

Zone Write Locking 区域写锁定

区域写入锁定实现了每个区域的写入锁定,以序列化针对同一区域的写入请求的执行。 这个特性不能保证写命令总是在区域写指针的位置发出:这是写 I/O 发出者的责任。 区域写入锁定仅保证应用程序、文件系统或设备映射器目标发出写入命令的顺序将受到块 I/O 堆栈的尊重。 因此,分区块设备的表现良好的用户将避免未对齐的写入命令失败。

区域写入锁定不会以任何方式影响读取命令。 读取请求的序列化和处理方式与常规块设备不同。

Initial Implementation

区域写锁定首先在内核 4.10 的 SCSI 磁盘驱动程序(块层之下)中实现,对已由块 I/O 调度程序传递到设备调度队列的请求进行操作。

这种早期实施依赖于 SCSI 层可以延迟向设备发出任何请求的事实。 通过维护每个区域一个位的位图,SCSI 磁盘驱动程序在看到写入命令时将区域标记为锁定。 此处更详细地介绍了此算法:

  1. 如果要发送到设备的下一个命令不是写入命令,则立即发送该命令。
  2. 如果分派的下一个命令是写入命令,则检查命令的目标区域的区域写入锁定位:
    i. 如果写命令的目标区域未写锁定(即,该位未设置),则该区域被锁定,并且向设备发出写命令。 这两个 操作都是在设备请求队列自旋锁下原子执行的。
    ii. 如果目标区域已被锁定(即该位已设置),则 SCSI 磁盘驱动程序会暂时延迟向设备发出命令,直到区域写入锁定被释放。
    iii. 当一个写命令完成时,该命令的目标区域的区域写锁被释放,并且调度过程被恢复。 这意味着如果调度队列头部的命令针对同一区域,则可以发出命令(当写入命令完成时)(步骤 2.a)。

注意 :如上所示实施的区域写入锁定还可以防止 SAS HBA 或 SATA 适配器意外重新排序命令。 AHCI 规范没有定义向设备发出命令的明确顺序。 结果,许多芯片组无法保证命令的正确顺序。

尽管此实现为传统的单队列块 I/O 路径提供了写入顺序保证并且不依赖于任何特定的 HBA,但它有几个限制:

  • 潜在的性能下降 : 对任何区域的任何写入命令都会导致命令调度处理停止。 这可以防止分派所有其他命令,包括读取命令。 这会限制在以高队列深度操作设备时通过设备级命令重新排序获得的性能优势。 极端情况是
### 关于 `dm-zoned` 的介绍 #### 设备映射器模块中的 `dm-zoned` 设备映射器(Device Mapper)是一个 Linux 内核框架,用于管理块设备的抽象层。它允许创建虚拟块设备,这些设备可以基于其他物理或逻辑块设备构建复杂的功能[^3]。 `dm-zoned` 是 Device Mapper 中的一个特定目标类型,旨在处理分区设备上的写入操作优化。对于现代大容量 SSD 和 HDD 存储介质而言,它们通常具有内部区域划分特性,即所谓的 Zoned Block Devices (ZBD),这使得某些部分只支持顺序写入而不能随机覆盖旧数据。为了更好地适应这种新型存储技术并提高性能,Linux 社区开发了 `dm-zoned` 来作为解决方案之一[^1]。 当使用 `dm-zoned` 时,会通过识别底层设备是否为分区分块设备来决定如何管理和调度 I/O 请求。如果检测到的是一个 zone-aware 或者 zoned 型态的目标,则该驱动程序将会按照相应的规则执行读/写命令序列化控制以及重定位等动作以确保最佳效率。 此外,在初始化过程中,`dm-init()` 函数负责启动整个 Device Mapper 模块,并调用一系列必要的子功能完成设置工作;而对于具体像 `dm-zoned` 这样的组件来说,其配置参数可能涉及到指定哪些实际磁盘应当被当作带状结构看待等问题。 ```c // Example of initializing a dm-zoned target within the kernel code. static int __init dm_zoned_init(void) { // Initialization logic here... } module_init(dm_zoned_init); ``` #### 数据结构关联 在实现上,`dm-zoned` 需要依赖一些核心的数据结构来进行有效的资源管理和请求转发。例如: - **struct dm_dev**: 描述了一个低级别的块设备实例,包含了指向底层 block_device 结构体的指针以及其他元信息,如文件访问权限和名称等属性。 - **set_capacity()**: 此函数用来设定给定通用磁盘对象 (`gendisk`) 所表示的实际大小,这对于正确反映新加入系统的分区或者调整现有卷尺寸非常重要[^2]。 综上所述,`dm-zoned` 提供了一种机制让操作系统能够充分利用带有内置区域特性的现代化固态硬盘和其他类型的持久性内存装置所带来的优势。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值