关注了就能看到更多这么棒的文章哦~
Parallelizing filesystem writeback
By Jake Edge
June 12, 2025
LSFMM+BPF
Gemini flash translation
https://lwn.net/Articles/1024402/
文件系统回写是将页面缓存(page cache)中“脏”(已写入)数据刷新到存储设备的过程。在 2025 年 Linux 存储、文件系统、内存管理和 BPF 峰会(LSFMM+BPF)上,Anuj Gupta 主持了一场关于并行化回写过程所做工作的存储和文件系统联合会议。现有单线程回写所遇到的一些性能问题,在去年峰会的一次会议上曾被提及,当时讨论了并行回写的想法。
Gupta 首先指出,议题提案的发布者 Kundan Kumar 原本应主持本次会议,但他未能出席。Kumar 和 Gupta 都一直在开发一个并行回写原型;本次会议旨在收集关于该原型的反馈。
目前,缓冲 I/O 的回写是单线程的,尽管应用程序正在发出多线程写入,这就可能导致出现竞争。在内核中,后备存储设备由一个BDI (块设备信息, struct backing_dev_info
)表示,每个 BDI 都包含一个单一的回写线程,用于处理其中嵌入的struct bdi_writeback。每个 bdi_writeback
都带有一个需要回写的 inode 列表和一个delayed_work 实例,这使得整个过程是单线程的。
Gupta 表示,根据 Dave Chinner 和 Jan Kara 在议题提案讨论中的想法,他与 Kumar 添加了一个 struct bdi_writeback_ctx
来包含 bdi_writeback
的上下文信息。BDI 中增加了一个回写上下文数组,这使得一个 BDI 可以有多个线程执行回写。这可以在 Kumar 于五月底发布的补丁系列中看到。他们认为可以增加两个并行度级别,但在原型中,他们专注于高层并行,将低层并行留待后续工作。
Gupta 说,高层并行根据文件系统几何结构来划分工作。例如,XFS 具有分配组(allocation groups),可以用于将需要回写的 inode 划分到 BDI 的不同独立上下文中。低层并行可以通过在 bdi_writeback
中设置多个 delayed_work
条目来实现;在该层,不同类型的文件系统操作,例如 XFS 的块分配与纯覆盖写入,可以由独立的工作队列(workqueue)处理。
Christoph Hellwig 不确定分配组是否是用于回写 inode 分区(sharding)的正确选择。Gupta 表示,测试在使用分配组时哪些工作负载会受益将非常重要。并行回写将是一个可选功能;如果它对用户的工作负载没有益处,用户可以禁用它。
Amir Goldstein 询问了当前单线程回写瓶颈的严重程度。Gupta 表示他没有相关数据。Chris Mason 说,在他的测试中,这在很大程度上取决于是否启用了大页(large folios);最容易看出单线程回写性能问题的方法是为 XFS 禁用大页。在一些简单的测试中,当禁用 XFS 的大页时,他在内核回写线程饱和之前能达到大约每秒 800MB 的速度。启用大页后,这个数字提高到大约每秒 2.4GB。
Hellwig 好奇在没有大页的情况下,周期花费在哪里。Mason 说他记不清细节了,不过页面被大量移动到不同的列表中。Matthew Wilcox 建议,XArray 应用程序接口(API)可能也是问题的一部分,因为没有 API 可以清除一系列页(folios)上的脏位。如果内核是逐个清除这些位,那可能是一个瓶颈;它可以被修复,但他还没有找到时间去做。
Jeff Layton 表示,网络文件系统需要某种方式来限制回写过程中的并行化程度。可能存在底层网络状况,需要限制并行回写。Gupta 承认了这一需求,Hellwig 也表示本地文件系统有时可能也需要这样做。Hellwig 希望看到改变的一点是 Btrfs 内部用于通过多个线程进行带压缩和校验和回写的机制;拥有一个通用的多回写线程解决方案“可以移除大量冗余代码”。他担心其他文件系统会采用那段代码,因此拥有一个通用解决方案可以避免这种情况发生;Mason 表示他不反对这个想法,尽管可能存在需要特殊处理回写的大文件。
通过远程连接,Jan Kara 表示他听到的情况是,大多数人的兴趣在于低层并行,这将并行化单个 inode 的回写。他提醒说,这样做存在各种问题,包括可能影响数据完整性度量的问题,因为写入操作会以不同的顺序进行。
Hellwig 表示,用于跟踪回写 inode 的“类似全局的链表”是一种已知会导致可伸缩性问题的数据结构。增加更多线程来处理这些列表会使情况变得更糟;他想知道是否改用 XArray 会更好。使用分配组来分片 inode 列表(或 XArray)对 XFS 来说是有意义的——其他文件系统可能有自己显而易见的分片选择——但线程的管理可以独立于列表的管理。可以使用其他标准来确定处理特定 inode 的线程。
Mason 表示同意,并想提出类似的想法。他认为,对于多线程回写的第一个版本,保持单个 inode 列表将是合理的。与其研究如何将 inode 分片到不同的列表中,不如“专注于能够一次性分派多个 inode 进行回写”;这将有助于确定锁竞争发生在哪里。Gupta 担心 inode 列表的锁竞争问题,但 Kara 认为与回写所需的其他所有工作相比,这不会那么显著。
Goldstein 表示,一旦该功能的基本原理运作正常,为文件系统提供一种方式来帮助为不同线程选择 inode 可能会有意义。文件系统可能拥有能够协助回写机制实现更好并行度的信息。
Mason 说了会议的最后一句话,他提到了在测试中发现但之前忘记的另一个瓶颈:释放干净页。一旦脏页被写入,这些干净页会由 kswapd 内核线程释放,这又导致了另一个瓶颈。他建议可能也需要在此处增加一些并行性。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~