LWN:folio的最新情况!

共 4442字,需浏览 9分钟

 ·

2022-05-18 16:29

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

A memory-folio update

By Jonathan Corbet
May 4, 2022
LSFMM
DeepL assisted translation
https://lwn.net/Articles/893512/

folio 项目还不到两年,但它已经导致了对内核的内存管理以及文件系统层的重大改变。虽然已经做了很多工作,但仍有不少尚未完成。在 2022 年 Linux 存储、文件系统、内存管理和 BPF 峰会的开幕全体会议上,Matthew Wilcox 提供了关于 folio 迁移方面的最新情况,并主持了关于有待完成的工作的讨论。

Wilcox 首先概述了 folio 的工作,更完整的描述可以在之前 LWN 文章中找到。简而言之,folio 是一种表示一组物理上连续的 base page 的方式。它是对内存管理子系统中长期存在的混乱状况的解决方法,一直以来, "page" 可能指一个 base page,也可能是一个更大的 compound page。添加一个新的术语可以消除 "page" 这个术语的歧义,并且简化许多内存管理的接口。

除了让术语定义更加明确之外,还有另一个动机来推动 folio 工作。内核确实需要用比 4KB base page 更大的单位来管理内存。即使在典型的笔记本电脑上也有数百万个这样的 page;这么多的 page 都需要管理,处理起来也很麻烦,造成了大量时间和精力的浪费。不过,我们需要更好的接口来利用更大单位的内存管理;folio 就是要成为这种更好的接口。

Current status

folio 是由 struct folio 表示的;它本质上是一个 compound page 的 head page 的别名。在过去的一年中,Wilcox 一直在向内核中添加使用 folio 的地方;这个项目已经有了很大的进展,但还没有完成。

有一个没有答案的的问题是关于内核什么时候应该分配大的 folio,也就是那些包含一个以上 base page 的 page。现在只有 readahead 代码会进行这种分配;文件系统的 write path 仍然以 base page 为单位来进行。如果要对通过 readahead 得到的 folio 进行写入,他们会看到并使用这些 folio。不过,对文件的追加(append)将总是使用 base page。几乎可以确定,在 write path 中使用大的 folio 是有好处的,但有必要弄清楚应该采用什么标准来创建它们。

同时,将文件系统代码转换为使用 folio 的过程仍在继续。Wilcox 鼓励文件系统开发者尽可能地寻找已经存在的基础设施,而不是自己重新实现它。他指出了最近由 David Howells 重写过的网络文件系统的支持层代码。对于文件系统来说,如果能不再使用旧的 buffer-head API,尽可能使用相对较新的 iomap 的基础设施,也是一件好事。

Ted Ts'o 说,在转换到 iomap 方面如果能更多的指导,那会是非常有帮助的。他说,将一个文件系统迁移过来可能是一项艰巨的任务,但开发者应该都明白,这个任务是可以逐步完成的。例如,文件系统里的 read path 可以先被转换过去,暂时不改变 write path。这个信息可能确实有帮助,Wilcox 同意,尤其是因为 iomap 仍然缺少一些功能,比如对 fs-verity 或压缩等功能的支持。这些缺失在 write 方面往往比在 read 方面影响更大。

API complaints

Josef Bacik 说,Btrfs 的一个特别恼人的问题是,在获取文件系统级的 lock 之前,必须先获取内存管理子系统的 page lock。这在文件系统层面上很困难,并且阻碍了一些功能的实现,比如 range locking。他希望看到这个问题得到解决,但他也知道这并不容易。Wilcox 承认,这个问题根本不在他的考虑范围之内,但他一定会去研究这个问题。Chris Mason 指出,这个问题并不是 Btrfs 所独有的,其他文件系统多年来也遇到过类似的困难。

Bacik 还说,由内存管理来触发的 page reclaim 也会有问题,而且文件系统的接口不是很好。他说,如果能够将 "请释放你现在能释放的任何内存 "这样的请求与释放指定 page 的请求区分开来就好了。Wilcox 说,内核的许多回收机制可能不再适用了;它是在文件系统能力远不如现在的时候设计的。现在好的文件系统已经可以做到让所有的驱动器都忙于 writeback 操作了;如果内存管理代码要求文件系统代码这边把指定 page 释放掉,其实文件系统能做的真的不多。他建议说,也许内存管理子系统应该简单地停止要求回收那些已经位于 LRU 列表末尾的 page。

他说,有一个可能的方法来测试这个想法;也许文件系统应该简单地删除他们对 writepage() 这个 address-space operation 的实现代码。Howells 说,他已经在 AFS 文件系统中这样做了,结果似乎不错。但其他一些文件系统比如说 9P,就比较困难了。

Ts'o 说,问题是内存管理子系统正试图同时解决多个问题。当应对全局内存压力时,它只需要释放一些 page,并不会挑剔是哪里的 page。但是,一旦有 cgroup 牵涉进来,那么就必须要在相应的 container 内缓解内存压力,这就要求内存回收需要更有针对性。在进行 compaction 压缩来创建 huge page 时,就需要释放指定的 page。这些情况都需要独立地进行考虑。移除 writepage()可能有助于解决全局的问题,但释放指定 page 的需求并没有消失。

Wilcox 表示,希望广泛使用大号的 folio 页将至少有助于解决 compaction 问题,因为会有更少的内存碎片了。在一些 benchmark 测试中,他看到 LRU list 的长度减少了 1000 倍,这 "太疯狂了(太棒了)"。

另一方面,他说,一个由大号 folio 导致的潜在问题可能是会有一些 write amplification (写放大)。是否 dirty 这个状态信息是在 folio 层面上来记录追踪的,而不是在其中所包含的具体某个 base page 层面上;当写出数据的时候,即使只有一个字节发生了变化,整个 folio 也会被写入。这将增加系统使用的写入带宽,但也应该有助于减少 copy-on-write 文件系统中的碎片化问题。他说,他预计不会有 "严重的麻烦"。

其他人就没有他那么确定了。Mason 指出,Jens Axboe 已经付出了相当大的努力,使在 io_uring 中进行小型操作(small operation)变得容易。这项工作主要是出于对 write-bandwidth 的担忧。Axboe 补充说,带宽确实会是一个问题,但在读取方面比写入方面的影响更大。对于这个问题究竟有多大影响,与会者进行了一些讨论;一位开发者指出,具体情况会根据所使用的文件系统而有差异。对于一个具有高延迟的网络文件系统来说,写太多的数据可能比在服务器上做多次往返交互要更好。大家普遍认为,需要更好的衡量标准来正确理解这种情况。

Long-term goals

接着,Wilcox 说,他仍在把文件系统提供的 address-space operation 转换为 folio 的过程中,还有几处需要修改。在许多情况下,这种 "转换" 只是改变一个函数原型,使其接受一个指向 folio 结构的指针,而不是指向 page 结构的指针,然后再增加一行代码,比如:

struct page *p = (struct page *) folio;

他说,这种模式是 "闻起来不像是好代码";它能说明相关的代码需要进一步的改动。我们的计划是最终将每个文件系统都转换为 folios,但不一定要使用大号的 folio。

这项工作背后有一个潜在动机:他希望最终能从 struct page 中删除一个大的 union 成员,这需要文件系统都不再使用这个结构。他说,内存管理的开发者希望把更多的信息放到 struct page 中,但有很强的理由来阻止让这个结构变得更大。因此,他想缩小这个 struct;也许有一天,它可以被减少(从 64 字节)到一个单个指针。更棒的是,这可能是指向 folio 的一个指针,而不是指向每个 page 的一个 structure,使内核能够拿回目前用于容纳 struct page 的 1.6% 的内存来作为其他用途。

他说,这将使公司能够节省内存相关的开销,并将其用于派遣他们的开发人员来参加更多的会议。

Howells 说,最终摆脱 write_begin() 和 write_end() 这些 address-space operation 就太棒了;Wilcox 同意,说它们最初是为 ext3 的需求而设计的,后来的文件系统也不得不适应这种模式。Goldwyn Rodrigues 指出,iomap 目前没有使用这些 callback。

Kent Overstreet 抱怨不应该把包含 callback 的结构到处传递,他说这是 API 设计的 "旧的模式"。Bacik 说,他并不真正关心 API,只要它能让他专注于 Btrfs,而不必担心内存管理的运作就好。Wilcox 回答说,他的大部分工作都是为了使文件系统能更容易编写,他希望 folios 能在这方面有所帮助。他说,文件系统中的任何东西都不应该关心 page,可能除了 page-fault 路径的代码之外。

不过,Overstreet 反对说,开发人员应该要更关心这些事情。内核的许多内部接口已经严重老化了;开发人员应该讨论痛点是什么,以及如何消除它们。Bacik 说,内核需要那些特别关心这些接口的开发者;他个人太疲惫了,无法承担更多任务。因此,他很高兴看到 folio 的工作;有一个关心接口的负责人,正在努力使它变得更好。他说,这是一项艰苦的、不辞辛劳的工作,并感谢 Wilcox 承担了这项工作。

Wilcox 在会议结束时承认,folio 的工作给许多其他开发者带来了额外的工作,并说他感受到了这些工作有多么繁重。开发者们已经向他详细说明了这些开销,只是有些人比其他人更加有礼貌。他感谢 Bacik 的言论,说他很高兴至少有人看到这项工作的好处。

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

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

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



浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报