news 2026/11/3 2:52:23

memory fault_dirty_shared_page

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
memory fault_dirty_shared_page

fault_dirty_shared_page是处理共享文件映射写缺页的最后一步,核心职责是:将页面标记为脏、解锁页面、更新时间戳,并执行脏页速率限制(throttling)。

核心实现

根据最新的 folio 化版本,其实现如下:

static vm_fault_t fault_dirty_shared_page(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct address_space *mapping; struct folio *folio = page_folio(vmf->page); bool dirtied; bool page_mkwrite = vma->vm_ops && vma->vm_ops->page_mkwrite; dirtied = folio_mark_dirty(folio); VM_BUG_ON_FOLIO(folio_test_anon(folio), folio); /* * Take a local copy of the address_space - folio.mapping may be zeroed * by truncate after folio_unlock(). */ mapping = folio_raw_mapping(folio); folio_unlock(folio); if (!page_mkwrite) file_update_time(vma->vm_file); /* * Throttle page dirtying rate down to writeback speed. * * mapping may be NULL here because some device drivers do not * set page.mapping but still dirty their pages * * Drop the mmap_lock before waiting on IO, if we can. */ if ((dirtied || page_mkwrite) && mapping) { struct file *fpin; fpin = maybe_unlock_mmap_for_io(vmf, NULL); balance_dirty_pages_ratelimited(mapping); if (fpin) { fput(fpin); return VM_FAULT_COMPLETED; } } return 0; }

关键设计点

1. 标记页面为脏

folio_mark_dirty(folio)是核心操作。注释指出,即使实际的写入操作尚未发生,在缺页处理阶段就标记脏位可以避免一些竞态条件,并可能提高效率。VM_BUG_ON_FOLIO断言该 folio 不是匿名页——这个函数只处理共享文件映射。

2. 在解锁前保存 mapping

注释解释了一个微妙的竞态:folio_unlock(folio)之后,另一个线程可能通过truncate将folio->mapping清零。因此必须在解锁之前通过folio_raw_mapping()取一份address_space的本地副本。address_space本身由vma->vm_file的引用保持存活,不会消失。

3. 更新时间戳

如果文件系统没有实现page_mkwrite回调,说明文件系统不关心写缺页的通知,此时内核直接调用file_update_time()更新文件的修改时间。

4. 脏页速率限制

这是该函数最复杂的部分。balance_dirty_pages_ratelimited(mapping)会让当前进程在脏页过多时睡眠等待,将脏页产生速率限制在回写速度之内。

由于等待可能睡眠,函数通过maybe_unlock_mmap_for_io()临时释放mmap_lock。如果确实释放了锁,函数返回VM_FAULT_COMPLETED而不是0,告知调用者缺页已处理完毕且锁已释放,无需重试。

历史演进

2023 年 folio 化:该函数从使用struct page迁移到struct folio,将四次隐式的compound_head()调用合并为一次,由 ZhangPeng 提交并经 Matthew Wilcox 和 Sidhartha Kumar 审查通过。

VM_FAULT_COMPLETED的引入:2022 年 Peter Xu 发现,对于共享文件映射的首次写缺页,由于fault_dirty_shared_page会释放mmap_lock进行脏页限流,调用者收到VM_FAULT_RETRY后必须重新执行整个缺页流程。他引入了VM_FAULT_COMPLETED返回值,让调用者知道“缺页已完成且锁已释放”,避免了不必要的重试。在 aarch64 测试中,这为顺序脏化 400MB shmem 文件的场景带来了约12% 的性能提升。

2025 年空指针修复:一个补丁修复了vma->vm_file为 NULL 时调用file_update_time导致的空指针解引用,将条件改为if (!page_mkwrite && vma->vm_file)。

调用场景

该函数由do_shared_fault()在页面映射建立完成后调用。完整流程是:__do_fault读取页面 →do_page_mkwrite通知文件系统 →finish_fault建立 PTE →fault_dirty_shared_page标记脏页并限流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 2:52:05

工业算法篇前言 从电流到比特

工业算法篇前言 从电流到比特 曾经有那么一个时代,被称为工业革命的奇迹。爱迪生的灯泡让黑夜不再可怕。麦克斯韦的电磁理论让电流产生了感应。 这场感应,法拉第先在实验台上看见了,麦克斯韦后来用几个方程把它写成了定律。人类管那段岁月叫…

作者头像 李华
网站建设 2026/11/3 2:51:13

问卷收回来的无效作答怎么筛:判据、剔除比例与说明写法三部分

回收的问卷里总有一部分是"点完了事"的。多数学位论文栽在这一步,不是因为删得多,而是删得没依据、写得没交代。判据先定、比例分项报、说明按句式落,三部分做完,方法节基本站得住。先看清问题:无效作答为什…

作者头像 李华
网站建设 2026/11/3 2:48:53

Seaborn常用绘图方法封装实战

文章目录 一、绘图前置准备 1.1 绘图数据集 1.1.1 数据集字段介绍 1.1.2 部分数据展示 1.2 导入相关库 1.3 解决中文乱码问题 1.4 字段中英文映射字典 1.5 图片保存方法 二、单变量绘图(类别数据) 2.1 柱状图 2.2 条形图 三、单变量绘图(连续数值数据) 3.1 直方图 3.2 核密…

作者头像 李华
网站建设 2026/11/3 2:47:01

一文理解基于瑞萨MCU的最小系统的启动流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/3 2:46:38

汽车防晒膜的六个技术判断:从「隔热率 99%」这个说法说起

汽车防晒膜的六个技术判断:从「隔热率 99%」这个说法说起 2026-10-29说明:本文的现场观察与部分样本数据,采集于乌鲁木齐市水磨沟区五星北路 223 号的 Polarie拜瑞膜猩超级工厂店(拜瑞 NO.XJ-001 超级工厂店 / 威固 VKPPF2182 / 龙…

作者头像 李华