什么时候应该在内核 blockdev 驱动程序中使用 REQ_OP_FLUSH? (REQ_OP_FLUSH bio 会刷新脏 RAID 控制器缓存吗?)
When should I use REQ_OP_FLUSH in a kernel blockdev driver? (Do REQ_OP_FLUSH bio's flush dirty RAID controller caches?)
我什么时候应该在我的内核 blockdev 驱动程序中使用 REQ_OP_FLUSH,接收 REQ_OP_FLUSH(或等效的 SCSI 命令)的硬件的预期行为是什么?
在 Linux 内核中,当 struct bio
被标记为 REQ_OP_FLUSH
以回写模式传递到 RAID 控制器卷时,RAID 控制器是否应该刷新其脏缓存?
在我看来,这就是 REQ_OP_FLUSH
的目的,但这与想要快速写回不一致:如果缓存是电池供电的,控制器不应该忽略刷新吗?
在 ext4's super.c ext4_sync_fs() function 中,当通过 barrier=0
安装选项禁用屏障时,写入会跳过对 blkdev_issue_flush()
的调用。这似乎暗示 RAID 控制器会在被告知时刷新缓存...但是 RAID 固件是否曾经违反规则?
- 刷新行为是否取决于固件实现和制造商?
- 关于该主题的 SAS/SCSI 说明在哪里?
- 其他注意事项?
linux-block 邮件列表中的 Christoph Hellwig 说:
Devices with power fail
protection will advertise that (using VWC flag in NVMe for example) and [the Linux kernel] will never send flushes.
Keith Busch 在 kernel.org:
You can check the queue attribute, /sys/block/<disk>/queue/write_cache. If the
value is "write through", then the device is reporting it doesn't have a
volatile cache. If it is "write back", then it has a volatile cache.
根据个人经验,并非所有 raid 控制器都能正确设置 queue/write_cache,正如上面 Keith 所指出的;我们的 LSI 3516 显示“write through”,即使 MegaRAID 软件报告 LUN 处于“回写”状态。
如果您知道您的数组在 write-back 模式下有一个 non-volatile 缓存 运行 那么请确保它处于回写状态:
]# cat /sys/block/<disk>/queue/write_cache
write through
如果不是,请修复它:
]# echo "write back" > /sys/block/<disk>/queue/write_cache
所以关于何时在内核代码中标记 REQ_OP_FLUSH
的问题的答案是:每当您认为您的代码应该提交到磁盘时。由于块层可以 re-order 任何 bio
请求,
- 发送一个WRITE IO,等待其完成
- 发送flush,等待flush完成
然后你就可以保证磁盘上有#1 的 IO。
但是,如果正在写入的设备 cache_mode 处于“回写”模式,则刷新将立即完成,并且由您的控制器完成其工作并保留 non-volatile 缓存活跃,即使在断电后(BBU、超级电容、闪存等)。
我什么时候应该在我的内核 blockdev 驱动程序中使用 REQ_OP_FLUSH,接收 REQ_OP_FLUSH(或等效的 SCSI 命令)的硬件的预期行为是什么?
在 Linux 内核中,当 struct bio
被标记为 REQ_OP_FLUSH
以回写模式传递到 RAID 控制器卷时,RAID 控制器是否应该刷新其脏缓存?
在我看来,这就是 REQ_OP_FLUSH
的目的,但这与想要快速写回不一致:如果缓存是电池供电的,控制器不应该忽略刷新吗?
在 ext4's super.c ext4_sync_fs() function 中,当通过 barrier=0
安装选项禁用屏障时,写入会跳过对 blkdev_issue_flush()
的调用。这似乎暗示 RAID 控制器会在被告知时刷新缓存...但是 RAID 固件是否曾经违反规则?
- 刷新行为是否取决于固件实现和制造商?
- 关于该主题的 SAS/SCSI 说明在哪里?
- 其他注意事项?
linux-block 邮件列表中的 Christoph Hellwig 说:
Devices with power fail protection will advertise that (using VWC flag in NVMe for example) and [the Linux kernel] will never send flushes.
Keith Busch 在 kernel.org:
You can check the queue attribute, /sys/block/<disk>/queue/write_cache. If the value is "write through", then the device is reporting it doesn't have a volatile cache. If it is "write back", then it has a volatile cache.
根据个人经验,并非所有 raid 控制器都能正确设置 queue/write_cache,正如上面 Keith 所指出的;我们的 LSI 3516 显示“write through”,即使 MegaRAID 软件报告 LUN 处于“回写”状态。
如果您知道您的数组在 write-back 模式下有一个 non-volatile 缓存 运行 那么请确保它处于回写状态:
]# cat /sys/block/<disk>/queue/write_cache
write through
如果不是,请修复它:
]# echo "write back" > /sys/block/<disk>/queue/write_cache
所以关于何时在内核代码中标记 REQ_OP_FLUSH
的问题的答案是:每当您认为您的代码应该提交到磁盘时。由于块层可以 re-order 任何 bio
请求,
- 发送一个WRITE IO,等待其完成
- 发送flush,等待flush完成
然后你就可以保证磁盘上有#1 的 IO。
但是,如果正在写入的设备 cache_mode 处于“回写”模式,则刷新将立即完成,并且由您的控制器完成其工作并保留 non-volatile 缓存活跃,即使在断电后(BBU、超级电容、闪存等)。