LWN:利用page folio来明确内存操作!

Linux内存管理专题 - 第13章:匿名folio与swap / 包含PG_swapbacked等标志// 用于swap缓存链表管理...无文件背景的页帧集合(典型应用:用户态堆/栈内存、共享内存、COW页。 阅读详情

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

Clarifying memory management with page folios

By Jonathan Corbet
March 18, 2021
DeepL assisted translation
https://lwn.net/Articles/849538/

内存管理(memory management)一般是以 page 为单位进行的,一个 page 通常包含 4,096 个字节,也可能更大。内核已经将 page 的概念扩展到所谓的 compound page(复合页),即一组组物理连续的单独 page 的组合。这又使得 "page" 的定义变得有些模糊了。Matthew Wilcox 从去年开始就一直在研究一个叫做 "page folios" 的概念,希望能让人们重新关注这个问题。不过,目前还不清楚内存管理社区是否会接受这个概念。

从最底层来说,page 是一个由硬件实现的概念。对内存的跟踪以及判定是否位于 RAM 中这都是以 page 为基本单位来进行的。无论是哪种 CPU 架构,尽管可能会提供有限几种 page size,但一定会从中选择一个 "base" page size,最常见的选择仍然是 4,096 字节——这与 30 年前第一个 Linux 内核发布时的情况一样。

不过,内核经常需要获取更大块的内存(memory in larger chunks)。其中一个例子是管理 "huge pages",huge page 同样也是由硬件实现的。例如,x86 架构可以使用 2MB 的 huge page,在恰当的地方使用 huge page 可以提高性能。内核也会分配用其他 size 为单位来分配一组 page,通常是用于 DMA buffer 或其他那些需要使用连续的若干 page 的场景下。这种页面分组(grouping of pages)在内核中被称为 "compound page(复合页)"。

内核所管理的内存中,每一个 base page 都是用 system memory map 中的一个 page structure 来代表的。如果利用一组 base page 创建出了一个 compound page,那么就会对这组 pages 中的第一个 page("head page")的 page structure 打上一个特殊标记,从而明确指出这是一个 compound page。这个 head page 的 page structure 中的其他信息都是对整个 compound page 生效的。所有其他 page("tail pages")也都被标记出来,使用一个指针指向相关的 head page 的 page structure。关于 compound pages 的组织方式,请参见An introduction to compound pages。

这种机制可以很容易从 tail page 的 page structure 找到整个 compound page 的 head page。内核中的许多接口都利用了这一特性,但它带来一个歧义问题:如果某个函数收到参数是一个指向了 tail page 的 page structure,那么这个函数是应该针对这个 tail page 上执行、还是在整个 compound page 上执行?或者,正如 Wilcox 在 12 月对 folio 系列 patch 的第一封邮件中所说的:

一个有 struct page 参数的函数通常预期收到的是一个 head page 或者 base page,如果给它一个 tail page 的话它就会出现 BUG。有的函数也许对任何 page 都可以支持,直接操作 PAGE_SIZE 这么多字节;有的函数可能针对 head page 会操作 page_size()这么多字节,而对 base page 或者 tail page 则操作 PAGE_SIZE 这么多字节;还有的可能收到 head page 或者 tail page 的时候都是按照 page_size()字节数来处理。我们现在的代码中以上情况都有出现。

(PAGE_SIZE 是一个 base page 的 size,而 page_size()则返回一个 page 的整体大小(它可能是个 compound page)。这个特殊的 API 似乎在历史上并没有出现过很多 bug,但是作为一个定义得这么含糊的接口,迟早会引发问题。

为了让这种情况的处理更加明晰,Wilcox 提出了 "page folio" 的概念,它实际上仍然是一个 page structure,只是保证了它一定不是 tail page。任何接受 folio page 参数的函数都会是对整个 compound page 进行操作(如果传入的确实是一个 compound page 的话),这样就不会有任何歧义。从而可以使内核里的内存管理子系统更加清晰;也就是说,如果某个函数被改为只接受 folio page 作为参数的话,很明确,它们不适用于对 tail page 的操作。

当 Wilcox 第一次发布这一组 patch 时,他强调的是这个改动会带来的另一个好处:任何函数,如果它必须要对整个 compound page 操作,但是却传入的只是一个 tail page,都必须将指向 tail page 结构的指针改为指向 head page 的指针。这通常是通过调用这个函数来实现的:

struct page *compound_head(struct page *page);

这个函数相对来说耗时很少,但是在对页面进行一次操作的过程中可能会被调用多次。这使得内核变大了(因为它是一个 inline 函数),并且也变慢了。一个接受 folio page 参数的函数就知道它收到的不会是 tail page,因此不需要调用 compound_head()。这样既节省了时间又节省了内存。

folio 类型本身被定义为一个简单的封装结构:

struct folio {
    struct page page;
};

根据这个结构,建立起一套新的基础设施。例如,get_folio()和 put_folio() 函数就跟 get_page()和 put_page() 函数一样,用来管理对 folio page 的引用,但不需要再调用 current_head()。此外还有一整套更高级的函数。其实这里真正耗费时间的工作是将各个内核子系统中的 API 转换为使用新的类型;Wilcox 并没有对这项工作的性质进行美化:

这里会是大量的繁重工作,并且都是破坏性的。包括修改每一个文件系统,以及许多设备驱动程序!不过我觉得这个工作是值得的。

到 3 月 5 日发布这组 patch 的第四个版本时,核心 patch 和转换 API 的 patch(Wilcox 没有发布出来)加起来大约有 100 个 commit,对于 review 来说,工作量已经非常大了。

也许是由于 patch 太大了,之前的邮件并没有引起许多讨论。不过针对最新的一版,Andrew Morton 看了一下,感到很担心:

天啊,这些改动真是太繁杂了。我们需要记住更多的东西,今后我们将永远有一个 "page "和 "folio "的混搭,到处都是从一个转换到另一个的代码。不断地增加 folio 访问代码以及操作代码来覆盖现有的 page 访问代码和操作代码,等等。

我不清楚这一切是否真的值得。

Hugh Dickins,也表示对这项工作缺乏兴趣。另一方面,Kirill Shutemov 和 Michal Hocko 都表示支持,至少在概念上支持。Dave Chinner 说,对于文件系统开发者来说,"这种抽象是绝对必要的",尤其是当 page cache 今后能够管理多种不同大小的 compound page 的时候。

所以,换句话说,对于这项工作是否能改善内核,目前核心开发者之间还没有达成共识。随着时间的推移,情况可能会发生变化,因为会有更多的人关注它,它的优势(或缺乏优势)将变得更加明显。但一般来说,在内存管理子系统中,变化往往是缓慢发生的,哪怕不是这么巨大、杂乱的改动也是慢慢进行的。还要注意的是命名的问题,很明显,"folio" 并不受欢迎,尽管目前还没有什么更合适的名字。因此,至少有一个结论是明确的:内核很可能会有类似 folio 这样的东西,但似乎不太可能很快发生。

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

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

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

TIBCO Jaspersoft Studio报表开发 使用教程-进阶版 本文学习内容容器定制二级目录三级目录 容器定制 二级目录 三级目录 阅读详情

相关推荐

@transactional滥用导致数据源连接池耗尽问题

@transactional滥用导致数据源连接池耗尽问题

qq_43205267的博客 1198

论好名字的重要性: Linux内核page到folio的变迁

一、引子Once upon a time,Netscape的大拿 Phil Karlton曾经说过:“There are only two hard things in Computer Science: cache invalidation and naming things”,成为程序界流传甚广的名言,可见取名是计算机科学中最难的两件事之一。取名,要用名字恰到好处地描述其想描述的事物,要体现代...

内核工匠 3401

从零开始:如何利用Device Monitoring Studio构建高效数据监控系统

本文详细介绍了如何利用HHD Device Monitoring Studio从零开始构建高效数据监控系统。涵盖基础架构设计、核心功能解析、实战部署指南及高级数据分析技术,帮助用户实现非侵入式监控,提升设备调试和网络协议分析效率。特别适合物联网和工业自动化领域的开发者与运维人员。

weixin_29201859的博客 327

LWN:改进page-fault的可扩展性!

关注了就能看到更多这么棒的文章哦~Improving page-fault scalabilityBy Jonathan CorbetMay 29, 2023LSFMM+BPFDeepL assisted translationhttps://lwn.net/Articles/932298/某些话题总是每年都要回到开发会议上来讨论一次,通常是因为开发人员仍在努力针对某个特定的问题寻找一个可行的解决...

Linux News搬运工 1164

PaddleOCR训练自己的数据

一 、数据准备 采用PPOCRLabel标注自己的数据 PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,内置PP-OCR模型对数据自动标注和重新识别。使用Python3和PyQT5编写,支持矩形框标注和四点标注模式,导出格式可直接用于PaddleOCR检测和识别模型的训练。 1.1 安装PaddlePaddle pip3 install --upgrade pip # 如果您的机器安装的是CUDA9或CUDA10,请运行以下命令安装 python3 -m pip in.

zyb的博客 1万+

OMNET++ INET框架学习教程(一)

在自组网学习的道路上摸石头过河,帮你快速入门OIMNET++平台下的INET框架。

NLDwangzhe的博客 6562

Linux 内存管理之page folios

Linux内核5.16版本引入page folio新机制,旨在解决传统内存管理中长期存在的"复合页"概念混乱问题。传统复合页由头页和尾页组成,导致内核函数接收page指针时无法明确区分应操作单个页还是整个复合页,造成接口语义模糊。page folio通过保证非尾页特性,使函数能明确操作整个内存单元,既提升了代码清晰度,又通过减少compound_head()调用优化了性能。

小立仔 2185

硬件工程师提前批真题及答案解析2

我们需要考虑题目可能的简化假设,即输入电阻 Ri​ 可能是 rbe​ 和 βre​ 的组合,但题目可能简化为: Ri​≈rbe​+βre​。由于锗管的正向导通电压较小(0.2 V~0.3 V),而硅管的正向导通电压较大(0.6 V~0.7 V),因此-4.7 V的电压差不符合硅管的特性,而更接近锗管的特性。在三极管电路中,静态电位是指在无信号输入时,三极管各电极的直流电压。re​ 是动态发射极电阻,通常可以近似为 re​=IE​VT​​,但在题目中已经给出了 re​=300Ω,因此可以直接使用这个值。

XU157303764的博客 777

Linux 内存管理新特性 - Memory folios 解读

folio 是什么?它的直接价值有哪些?

阿里云云栖号 1565

2025华为杯第二十二届中国研究生数学建模竞赛D题:低空湍流监测及最优航路规划 - 完整解题分析+完整MATLAB源码!(上篇)

🎓 本文收录于 《滚雪球学数学建模》专栏,本专栏专注于从零基础出发,带你循序渐进掌握数学建模的核心方法与思维路径。通过“滚雪球式”学习法,从最简单的生活化案例到经典建模工具,再到省赛、国赛真题实战演练,逐步积累知识与技能,帮助你搭建完整的建模体系。无论你是刚接触建模的新生,还是希望提升科研与竞赛能力的学者与工程师,本专栏都将为你提供一条清晰、高效、可实操的建模成长路线,助力你快速进阶,突破难点,迈向数学建模竞赛与实际应用的更高峰 🚀!

**My Coding Family** 2584

perl 安装DBI和DBD

还可以从cpan.perl.org站点下载tar压缩文件形式的源代码发行版本,解压缩后,切换到相应的文件目录 cd DBI-1.54 perl Makefile.PL make make test make install 安装DBD时候 需要export ORACLE_HOME 验证安装: perldoc DBD::Oracle perldoc DBI 在线文档; perldoc -m

zhaoyangjian724的专栏 1754

LWN:关于readahead的讨论!

关注了就能看到更多这么棒的文章哦~A discussion on readaheadBy Jake EdgeJune 15, 2022LSFMMDeepL assisted translationhttps://lwn.net/Articles/897786/Readahead 是一种 I/O 优化,让系统读取的数据要比应用程序所要求的更多,因为相信这些额外的数据很快会被...

Linux News搬运工 478

Android 12.0 framework系统修改安兔兔等显示的屏幕尺寸大小功能实现

在12.0的系统rom定制化开发中,在使用第三方app检测系统的一些信息中,比如安兔兔 设备信息等检测app中,有时候显示的屏幕尺寸大小和 产品规格书等信息不同,稍微有些差异,所以就需要看下系统framework层中,相关的设备信息是怎么读出来的,然后做些调整 接下来就来分析相关功能

安卓兼职framework和app工程师的博客 476

LWN:folio的最新情况!

关注了就能看到更多这么棒的文章哦~A memory-folio updateBy Jonathan CorbetMay 4, 2022LSFMMDeepL assisted translationhttps://lwn.net/Articles/893512/folio 项目还不到两年,但它已经导致了对内核的内存管理以及文件系统层的重大改变。虽然已经做了很多工作,但仍有不...

Linux News搬运工 1448

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

LWN:内核热点: folio,多代LRU,以及Rust!

关注了就能看到更多这么棒的文章哦~The kernel radar: folios, multi-generational LRU, and RustBy Jonathan CorbetJ...

Linux News搬运工 1822

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LWN: folio 改动未能合入!

关注了就能看到更多这么棒的文章哦~The folio pull-request pushbackBy Jonathan CorbetSeptember 10, 2021DeepL assi...

Linux News搬运工 417

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

LWN:page在2024年的状况!

关注了就能看到更多这么棒的文章哦~The state of the page in 2024By Jonathan CorbetMay 15, 2024LSFMM+BPFChatGPT translationhttps://lwn.net/Articles/973565/引入folio结构来描述页面组,是近年来内核中最为基础的转变之一。由于 folio 转换工作影响到了许多子系统,因此在 2024...

Linux News搬运工 359

LWN:9月份LPC上关于folio的一次讨论!

关注了就能看到更多这么棒的文章哦~A discussion on foliosBy Jake EdgeSeptember 22, 2021LPCDeepL assisted transla...

Linux News搬运工 599

LWN: 冻结page引用计数!

关注了就能看到更多这么棒的文章哦~Freezing out the page reference countBy Jonathan CorbetDecember 6, 2024Gemini-1.5-flash translationhttps://lwn.net/Articles/1000654/`page` 结构体是内核内存管理子系统的核心(目前是这样),其关键部分是存储在 `refcount`...

Linux News搬运工 1190

LWN:FUSE 改用 folio 页集时出现的困扰!

关注了就能看到更多这么棒的文章哦~FUSE folio conversion confusionBy Daroc AldenFebruary 18, 2025Gemini-1.5-flash translationhttps://lwn.net/Articles/1008714/内核开发者们一直在努力将各种内部接口转换为使用folios(页集);虽然这个过程一直在进行,但由此引入的回归(regr...

Linux News搬运工 959

LWN:把slab从struct page中移出来!

关注了就能看到更多这么棒的文章哦~Pulling slabs out of struct pageBy Jonathan CorbetOctober 8, 2021DeepL assist...

Linux News搬运工 447

LWN:让kernel使用更大的block size!

关注了就能看到更多这么棒的文章哦~Moving the kernel to large block sizesBy Jake EdgeSeptember 27, 2023OSSEUChatGPT translationhttps://lwn.net/Articles/945646/使用更大的块大小(block size)进行I/O内核是存储和块层领域经常讨论的话题。这个话题在2023年5月的Lin...

Linux News搬运工 957

LWN:参与者共同记录page flags!

关注了就能看到更多这么棒的文章哦~Documenting page flags by committeeBy Jonathan CorbetMay 22, 2024LSFMM+BPFGemini-1.5-flash translationhttps://lwn.net/Articles/974515/对于系统中的每个内存页面(page),内核都会维护一组页面标志(page flag),描述页面的使...

Linux News搬运工 546

LWN:2025 疯狂的 mapcount!

但是,这种优化只会使专有性问题更加难以回答,尤其是在存在部分映射的页组(其中只有部分页面映射到地址空间中)的情况下。所有这些工作的结果是,内核可以更好地处理任何给定的页组是被独占还是共享映射,尽管它仍然可能偶尔得出结论,即页组在未被独占映射时被共享映射。它们有自己的映射计数,本质上是它们包含的页面的映射计数的总和。对于单个页面,专有性问题很容易回答:如果映射计数为 1,则映射是独占的,否则是共享的。但是,如果映射计数是在页组级别维护的,则该规则不再适用,因为页组级别的计数几乎不可能是 1。

Linux News搬运工 1661

LWN:5.17 合并窗口的剩余部分!

关注了就能看到更多这么棒的文章哦~The rest of the 5.17 merge windowBy Jonathan CorbetJanuary 24, 2022DeepL assi...

Linux News搬运工 454

LWN:文件系统支持block size超过page size!

关注了就能看到更多这么棒的文章哦~Filesystem support for block sizes larger than the page sizeFebruary 20, 2025This article was contributed by Pankaj RaghavGemini-1.5-flash translationhttps://lwn.net/Articles/1009548/...

Linux News搬运工 1389
上一篇: LWN:建立一个SSH蜜罐!
下一篇: LWN:COW以及它最近引出的一系列问题 - 第一部分
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值