Zoned Storage-Linux Kernel Support 之 Write Ordering Control
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 磁盘驱动程序在看到写入命令时将区域标记为锁定。 此处更详细地介绍了此算法:
- 如果要发送到设备的下一个命令不是写入命令,则立即发送该命令。
- 如果分派的下一个命令是写入命令,则检查命令的目标区域的区域写入锁定位:
i. 如果写命令的目标区域未写锁定(即,该位未设置),则该区域被锁定,并且向设备发出写命令。 这两个 操作都是在设备请求队列自旋锁下原子执行的。
ii. 如果目标区域已被锁定(即该位已设置),则 SCSI 磁盘驱动程序会暂时延迟向设备发出命令,直到区域写入锁定被释放。
iii. 当一个写命令完成时,该命令的目标区域的区域写锁被释放,并且调度过程被恢复。 这意味着如果调度队列头部的命令针对同一区域,则可以发出命令(当写入命令完成时)(步骤 2.a)。
注意 :如上所示实施的区域写入锁定还可以防止 SAS HBA 或 SATA 适配器意外重新排序命令。 AHCI 规范没有定义向设备发出命令的明确顺序。 结果,许多芯片组无法保证命令的正确顺序。
尽管此实现为传统的单队列块 I/O 路径提供了写入顺序保证并且不依赖于任何特定的 HBA,但它有几个限制: