【问题标题】:Is it a safe to use Direct-IO write and Page Cache read at the same time?同时使用 Direct-IO 写入和页面缓存读取是否安全?
【发布时间】:2020-04-27 21:45:37
【问题描述】:

例如,打开一个文件两次,一个 fd 直接 io 写入,另一个 fd 读取页面缓存?

如何定义safe:从direct-io fd写入一些数据,然后期望从page-cache fd读取它们immediately

【问题讨论】:

  • 当您的意思是直接 io 写入时指的是 DMA?
  • 定义“安全”的含义。
  • @AndrewHenle 从 direct-io fd 写入一些数据,然后期望立即从 page-cache fd 读取它们
  • @Trickzter 不,只有用户空间程序,带有文件系统。

标签: c caching linux-kernel ext4 page-caching


【解决方案1】:

我认为directIO写入文件对于以后对该文件的缓存读取应该是相当安全的,但是读取的性能可能较低(写入的数据没有保存在页面缓存中,必须从真实存储中读取)。但确切的代码路径可能取决于所使用的文件系统。

这篇帖子https://lwn.net/Articles/776801/提到直接IO有失效语义:

至少对于某些文件系统,在页面上执行直接 I/O 读取将强制该页面退出缓存

book 在“写入缓存”部分列出了 3 种写入策略:不写入、直写、回写。直接 I/O 可能是 write() 系统调用的“不写”变体。

对单个文件使用多个 fd 是安全的,因为数据由使用 inode 的 FS 代码管理。两个 fd 都会指向同一个 inode。

2013 年邮件列表中有一个主题https://lists.kernelnewbies.org/pipermail/kernelnewbies/2013-July/008660.html,TLDR 是:

从内核开发人员的角度来看: 内核驱动程序保证页面缓存和 使用 O_DIRECT 传输的数据。 ...

  1. 不用担心页面缓存和数据之间的一致性 使用 O_DIRECT 传输。内核将在之后使缓存失效 O_DIRECT 写入并在 O_DIRECT 读取之前刷新缓存。
  2. 使用互斥锁或信号量(或众多选项 [1] 中的任何一个) 防止在 IPC 期间使用共享的常见同步问题 文件。

因此,虽然直接写入会从页面缓存中清除文件的已写入部分,但写入器和读取器之间存在一定的竞争。因此,如果您的读者想要获取更新的数据,则需要互斥锁或其他同步。只有在直接 IO write() 系统调用结束后,页面缓存才会被清除。

有时不建议混合使用:https://medium.com/databasss/on-disk-io-part-1-flavours-of-io-8e1ace1de017 "不鼓励同时使用 Direct IO 和页面缓存打开同一个文件,因为即使数据在页面缓存中,也会对磁盘设备执行直接操作,这可能会导致不良结果。"

【讨论】:

  • 感谢您的详尽解释。
猜你喜欢
  • 2017-04-21
  • 2016-10-14
  • 1970-01-01
  • 2014-06-14
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多