LWN:提高 FUSE writeback 性能!

关注了就能看到更多这么棒的文章哦~

Improving FUSE writeback performance

By Jake Edge
May 6, 2025
LSFMM+BPF
Gemini-1.5-flash translation
https://lwn.net/Articles/1019522/

在 2025 年 Linux 存储、文件系统、内存管理和 BPF 峰会 (LSFMM+BPF) 上的一次文件系统 (filesystem) 和内存管理 (memory-management) 联合会议上,Joanne Koong 主持了一场关于改进用户空间文件系统 (Filesystem in Userspace - FUSE) 层回写 (writeback) 性能的讨论。回写 是将写入文件系统的数据实际刷写到磁盘 (disk) 的过程;它是将页缓存 (page cache) 中的脏页 (dirty pages) 写入存储介质的过程。当前的 FUSE 实现会分配不可移动内存 (unmovable memory),然后将脏数据复制到其中,再开始回写,这很慢;Koong 希望改变这种行为。会议结束后,她 发布了一组补丁集 (patch set),这组补丁集已被 FUSE 维护者 Miklos Szeredi 采纳。

Koong 首先描述了当前的 FUSE 回写操作。对于每个脏页,都会在不可移动内存区域 (unmovable memory zone) 中分配一个临时页 (page),并将数据复制到该临时页。之后,对这些临时页启动回写,而原始页的回写状态可以立即清除。额外的分配 (allocation) 和复制 (copying) 操作代价很高,但这是必需的,以确保在回写操作 (writeback operation) 进行期间,这些页不会移动。

她表示,基准测试 (benchmarks) 表明,在没有临时页的情况下,写操作 (writes) 的吞吐量 (throughput) 提高了约 45%。除此之外,消除复制简化了 FUSE 的内部机制 (internals)。目前有一个红黑树 (red-black tree) 用于跟踪临时页,该树可以被移除。这也使得 FUSE 转换为使用大 folio (large folios) 的过程更加清晰。

回溯到去年 11 月,她 发送了一个提议的解决方案 (proposed solution),该方案移除了临时页,这意味着回写状态 (writeback state) 不会再立即清除。为了避免死锁 (deadlocks),该补丁集添加了一个新的映射 (mapping) 标志 `AS_WRITEBACK_INDETERMINATE` ,文件系统可以在 inode (索引节点) 映射上设置该标志,表示回写可能需要不确定的时间才能完成;FUSE 将在其映射上设置此标志,这可以用于避免回写机制 (writeback machinery) 中的死锁。

Koong 说,该补丁集被拒绝了,主要是因为它可能允许有 bug (buggy) 或恶意的 (malicious) FUSE 服务通过不完成某些页的回写来无限期地阻碍迁移 (migration)。这会增加内存碎片 (memory fragmentation),并阻碍分配连续内存 (contiguous memory) 的尝试。分配临时页也会导致内存碎片,但这些页是在不可移动内存中创建的,其碎片化问题不如可移动内存 (movable memory) 那么严重。FUSE 的其他部分已经存在这个问题,包括预读 (readahead) 和直写 splicing (writethrough splicing)(使用 splice() ),但“我们不应该试图增加更多此类问题,而应该尽可能地消除它”。

讨论中提到了几种选项,但最有希望的想法——提供一种机制 (mechanism) 在需要迁移 (migrate) 页时取消回写 (cancel writeback)——行不通。她说,问题在于页可能已经被 spliced (spliced),对于这些页,回写是无法取消的。另一个可行的可能性是在可移动区域 (movable zone) 中划出一块专用区域,用于存放可能在不确定时间内不可移动的页。这将把碎片化的影响限制在该区域的内存范围。另外,对于行为不端的非特权 (unprivileged) FUSE 服务,如果它们不能及时完成回写或有太多页处于回写状态,可以直接杀死它们。

David Hildenbrand 表示,曾有一些讨论建议禁止非特权 FUSE 服务使用 splicing ;“你不够值得信赖,不能让你这么做”。这将允许取消回写,但 Koong 不确定这是否是正确的方向。随后是一些快速进行且难以跟上的讨论,涉及避免可能导致死锁 (deadlock) 的各种边缘情况 (edge cases)。

Omar Sandoval 询问了直接杀死那些行为不端的非特权服务 (unprivileged servers) 的可行性,就像有人建议的那样。Koong 说这是一个合理的解决方案,尽管可能不向后兼容 (backward compatible),因为现有的服务没有预料到这一点。但她认为,作为一种保护机制 (protection mechanism),类似措施应该早就实施了。

Sandoval 询问了合理的超时 (timeout) 值应该设定为多少。这需要权衡;“如果你是一个 FUSE 服务,午餐时间出去了 30 分钟,我不在乎你的向后兼容性,你已经破坏了一切”。Hildenbrand 说这是一个难以解决的问题;任何选择的超时值有时都会太大或太小。有时数据足够重要,可以接受长时间等待,但例如 30 秒可能已经太长,无法阻碍分配 (allocation)。

他希望能找到一种简单的方法来处理页可以被迁移 (migrated) 的常见情况,这可能意味着禁止使用 splice() 。他想知道这种禁止 (prohibition) 会带来什么影响 (implication)。Koong 说可以对 FUSE 服务进行审计 (audited),检查是否使用了 splice() ,并与开发者 (developers) 讨论这个问题。Josef Bacik 表示,当非特权服务请求使用 splice() 时,内核 (kernel) 可以简单地回退到执行内部复制 (copy)。

他接着说,问题的症结似乎在于处于回写状态的内存的不可移动特性 (unmovable nature);如果能找到一种新方法,在不进行复制的情况下使用可移动内存 (movable memory),那将是理想的。“我们喜欢 splice() ,因为它更快,但这听起来我们需要发明一种新的零拷贝机制 (zero-copy mechanism),使用可移动内存”。

Jeff Layton 说,能够以非特权用户 (unprivileged user) 身份挂载 (mount) FUSE 文件系统 (FUSE filesystems) 使其问题重重;任何普通用户都可以启动一个服务,占用大量内存且处理不当。这正是系统 (system) 需要防范的;采取“严厉措施”如杀死服务 (server) 并非不合理。他建议找到一种方法来保持与现有服务 (servers) 的兼容性 (compatibility),并为新服务提供零拷贝机制 (zero-copy mechanism);在他看来,重写一些老的 FUSE 服务以利用新特性 (features) 并非不可能。Koong 表示同意,但她说这方面应该如何做由 Szeredi 决定;她不清楚他的想法是什么。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值