Linux脏页写回行为如果write()两次到同一页面

时间:2014-09-15 21:05:12

标签: linux linux-kernel

我理解默认的write()行为(如果文件没有使用O_DIRECT或O_SYNC打开等等)。在Linux上缓存的写 - 写操作在页面缓存中延迟。

考虑以下情况:

1)程序将1KB的数据写入偏移量为5000的文件,从而使相应的页面成为脏页

2)相同的程序稍后将1KB的数据写入同一个偏移的同一个文件,假设前一页还没有被pdflush刷新,那么内核会做什么呢?

我认为Linux内核可以执行以下操作之一:

a)在辅助write()发生之前刷新上一个脏页

b)先前的脏页被覆盖,而pdflush只在次写()到磁盘后刷新缓冲区

c)因为第二个write()使用了一个新的页面,我可能会出现根本错误。

3 个答案:

答案 0 :(得分:2)

您的问题的答案是以前的脏页被覆盖

在刷新线程将其写回到后备设备后,脏页将是干净的。但是即使页面被写回来也不再脏,它可能仍在用于文件的相同偏移量。

在以下条件下,页面将返回到伙伴系统。

  • 文件已关闭。因此,将释放此文件的所有缓存页面。
  • drop_caches is triggerd
  • 可用内存低于水印,缓存页面将被回收。

如果您对此感兴趣,我建议您添加 do_generic_file_read 中的登录以进行验证。 page = find_get_page(mapping,index)的结果可以显示与文件索引对应的实际页面结构地址。

http://lxr.free-electrons.com/source/mm/filemap.c#L1478

答案 1 :(得分:1)

内核刷新线程在系统初始化时启动,当有太多脏缓冲区时,它们会被激活,如果需要更多缓冲区并且内存很少的话。

如果系统中超出脏页(写回)比率,则在辅助write()之前刷新脏页,这意味着内存中的脏页数已超过certian阈值,即vm使用sysctl进行可调参数,除非您的应用程序不手动调用fsync()或sync()系统调用。

注意:在较新版本的内核中,每个支持设备信息(BDI)使用刷新线程替换了pdflush。 pdflush - 在2.6或更旧的内核中 冲洗 - 在2.6.32。

可以从/ proc / sys / vm / bdflush文件中调整这些内核线程:age_buffer,b_flushtime = jiffies + age_buffer

希望这有帮助!

答案 2 :(得分:0)

这取决于是否使用“稳定页写入”。

请参阅2012年LWN.net文章“ Optimizing stable pages”。 (优化是在不需要它们时自动不使用它们:-)。