什么时候应该在内核 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 固件是否曾经违反规则?

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 请求,

  1. 发送一个WRITE IO,等待其完成
  2. 发送flush,等待flush完成

然后你就可以保证磁盘上有#1 的 IO。

但是,如果正在写入的设备 cache_mode 处于“回写”模式,则刷新将立即完成,并且由您的控制器完成其工作并保留 non-volatile 缓存活跃,即使在断电后(BBU、超级电容、闪存等)。