当前位置: 首页 > news >正文

dirty file page

转自:https://www.cnblogs.com/zhiminyu/p/17330763.html

0.前言
Linux 内核Page Cache 和Buffer Cache 关系及演化历史 一文中讲过Linux 2.4之后将Page Cache和Buffer Cache 进行了融合,在buffer_head 中添加了b_page,很容易就能找到缓存的Page Cache,而buffer_head 的存在就是能够快速确定页中的一个块在磁盘中的地址。

Linux内核由于存在page cache, 一般修改的文件数据并不会马上同步到磁盘,会缓存在内存的page cache中,我们把这种和磁盘数据不一致的页称为脏页,脏页会在合适的时机同步到磁盘。为了回写page cache中的脏页,需要标记页为脏(dirty)。

脏页跟踪是指内核如何在合适的时机记录文件页为脏,以便内核在进行脏页回写时,知道将哪些页面回写到磁盘。匿名页不需要跟踪脏页,因为不需要同步到磁盘;私有文件页也不需要跟踪脏页,因为映射的时候,可写页会映射为只读,写访问会发生写时复制,转变为匿名页;所以只有共享的文件页需要跟踪脏页。跟踪有两个层面:一个是页表项记录,一个是页描述符记录。

访问文件页有两种方式:

一种是通过mmap映射文件;
一种是通过文件系统的write接口操作文件;
本文将对这两种方式进行讲解。在Linux内核中,因为跟踪脏页会涉及到文件回写、缺页异常、反向映射等技术,所以本文也重点讲解在Linux内核中如何跟踪脏页。

1. 引入脏页提高性能
Linux在设计IO模块的时候,认为读写操作的紧迫性是不一样的,读操作的紧迫性要高于写操作。所以Linux的写默认是延迟的,因为这样不仅仅可以显著的提高效率:

写操作合并:多次写操作才会真正的发起一次写物理磁盘,大幅提升IO性能;
IO栈中还有通用块层和IO调度层,在具体的文件系统层有文件在文件系统中的逻辑块映射,也就是文件的文件块在磁盘上对应的磁盘块的地址,这时候在通用块层会把这些信息封装成BIO对象,然后提交到gendisk->request_queue,在提交的过程中,如果BIO和已有的request中的BIO在物理地址上是连续的,那么这些BIO就会合并成一个request。在IO调度层,一次request就意味着一次IO,因为这时候磁盘需要重新寻址,所以这个合并其实是在io调度层入队列的时候完成的;
你可以通过iostat查看物理盘IO情况的时候看到对应的监控指标:rrqm/s、wrqm/s等;
读操作比写操作更紧迫:
通常延迟写物理磁盘不会导致进程挂起,写到page cache然后修改该页的PG_dirty标志即可返回(如果open的时候设置了sync标志或者调用了fsync、sync函数,那么会将写page cache的内容封装成一个IO request放到IO调度层的request_queue中,然后由调度层的调度算法来写到物理磁盘);
但是如果读操作读的时候page cache中没有缓存数据,读操作就需要去读物理磁盘,此时延迟读就会让用户感知,这就很糟糕了,用户就会感觉OS卡顿,Linux作为桌面系统的时候,他还是要优先保证和用户良好的交互性;
你还可以从IO scheduler的调度算法deadline的默认配置感受一下,读延迟是500ms,写延迟是5s,这就很明显的感受到Linux对读写操作紧迫性的区别对待;
2. mmap 映射的文件页
基本过程如下:

step1,通过mmap映射共享文件;
step2,第一次访问文件页时,发生缺页后读文件页到page cache,如果是写访问则设置相应进程的页表项为脏、可写;
step3,脏页回写时,会通过反向映射机制,查找映射这个页的每一个vma, 设置相应进程的页表项为只读,清脏标记;
step4,假如第二次写访问这个文件页时,脏页的处理有两种情况:
page cache中的文件页还未回写到磁盘(step3 之前), 此刻,这个文件页依然是脏页。因为相应进程的页表项为脏、可写,所以可以直接写这个页;
page cache中的文件页已经回写到磁盘(step3 之后), 此刻,这个文件页不再是脏页。因为页表项为只读,所以写访问会发生写时复制缺页异常,异常处理中将处理共享文件页映射,重新将相应进程的页表项为设置为脏、可写
2.1 第一次写访问文件页

/mm/memory.chandle_pte_fault->do_fault->do_shared_fault|->__do_fault //读文件页到page cache|->do_page_mkwrite|    ->vmf->vma->vm_ops->page_mkwrite|        ->filemap_page_mkwrite /mm/filemap.c|            ->set_page_dirty|                ->__set_page_dirty_buffers|                    ->TestSetPageDirty  //设置页描述符脏标记|                    ->__set_page_dirty  //page cache中标记页为脏 |->finish_fault  //设置页表项->alloc_set_pte->maybe_mkwrite  //设置页表项脏、可写

2.2 脏页回写

 1 /mm/page_writeback.c2  3 write_cache_pages4  5     ->clear_page_dirty_for_io  //对于回写的每一个页6  7         |->page_mkclean  //清脏标记  mm/rmap.c 8  9         |   ->page_mkclean_one  //反向映射查找这个页的每个vma,调用清脏标记和写保护处理
10  
11         |        ->entry = pmdp_invalidate(vma, address, pmd);
12         |          entry = pmd_wrprotect(entry);  //写保护处理,设置只读
13         |           entry = pmd_mkclean(entry);  //清脏标记 set_pte_at(vma->vm_mm, address, pte, entry) //设置到页表项中
14  
15         |->set_page_dirty

2.3 第二次写访问文件页
1)脏页还没有回写时(确切的说是调用clear_page_dirty_for_io之前),页描述符已经设置了脏标记,页表项已经设置了脏标记、可写。

这时可以直接写访问文件页,不会发生缺页。

2)脏页已经回写时(确切的说是调用clear_page_dirty_for_io之后),页描述符已经清除了脏标记,页表项已经清除了脏标记,且只读。

这时写访问文件页会发生写时复制缺页异常(访问权限错误缺页)。

调用链如下:

 1 /mm/memory.c2  3 handle_pte_fault4  5     ->if (vmf->flags & FAULT_FLAG_WRITE) {  //vma可写6           if (!pte_write(entry))  //页表项没有可写属性7               do_wp_page(vmf)  //写时复制缺页异常处理8  9                   ->if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED))  //是共享可写的文件映射vma
10                         wp_page_shared
11  
12                             |->do_page_mkwrite
13  
14                             |    ->vmf->vma->vm_ops->page_mkwrite
15  
16                             |        ->filemap_page_mkwrite /mm/filemap.c
17  
18                             |            ->set_page_dirty
19  
20                             |                ->__set_page_dirty_buffers
21  
22                             |                    ->TestSetPageDirty  //设置页描述符脏标记
23  
24                             |                    ->__set_page_dirty  //page cache中标记页为脏 
25                             |->finish_mkwrite_fault
26  
27                                  ->wp_page_reuse
28  
29                                      ->entry = maybe_mkwrite(pte_mkdirty(entry), vma);  //重新设置页表项脏、可写

2.4 再次写访问
重复上面步骤

3. write 接口操作的文件页
由于通过write接口访问文件页时,会读取文件页到page cache,不会映射到任何进程地址空间,所有这种方式跟踪脏页是通过设置/清除页描述符脏标记来实现。

3.1 第一次写访问文件页
会首先读文件页到page cache,然后将用户空间写缓冲区数据写到page cache,调用链如下:

 1 /fs/ext4/file.c2  3 ext4_file_write_iter4  5     ->__generic_file_write_iter6  7         ->generic_perform_write8  9             ->a_ops->write_begin   //写之前处理 分配page cache页
10  
11                 ->__block_commit_write
12  
13                     ->mark_buffer_dirty
14  
15                         ->__set_page_dirty  //设置页为脏(设置页描述符脏标记)
16  
17             ->iov_iter_copy_from_user_atomic  //用户空间写缓冲区数据写到page cache页

3.2 脏页回写

1 write_cache_pages  //mm/page-writeback.c 
2  
3 ->clear_page_dirty_for_io 
4  
5         ->TestClearPageDirty(page) //清除页描述符脏标记

3.3 第二次写访问文件页
脏页回写之前,页描述符脏标志位依然被置位,等待回写, 不需要设置页描述符脏标志位。

脏页回写之后,页描述符脏标志位是清零的,文件写页调用链会设置页描述符脏标志位。

4. 总结
1)对于mmap映射的共享文件页,因为这个文件页可能会被多个进程共享到多个vma中,所以通过页表项的脏标志位来跟踪脏页:第一次写访问发生缺页异常会读文件页到page cache中并设置进程的页表项的脏标志,回写之前(clear_page_dirty_for_io完成之前),页表项的脏标志是置位的,回写的时候(clear_page_dirty_for_io的调用)会通过反向映射机制将所有映射这个页的页表项的脏标志位清零并设置只读权限,回写之后(clear_page_dirty_for_io完成之后),再次的写访问会发生写时复制缺页异常,再次设置页表项的脏标志位,如此重复,从而跟踪了脏页。

2)对于直接通过write接口访问的文件页,因为这个文件页只会被读取到page cache中,并没有映射到任何进程地址空间,进程写访问是通过copy_from_user的方式,所以通过页描述符记录脏页。回写之前(clear_page_dirty_for_io完成之前),写文件的时候通过文件系统的写文件的调用链会设置页描述符脏标志位,回写的时候(clear_page_dirty_for_io的调用)会清除页描述符脏标志位,回写之后(clear_page_dirty_for_io完成之后),再次通过write接口写访问时,再次通过文件系统的写文件的调用链会再次设置页描述符脏标志位,如此重复,从而跟踪了脏页。

相关文章:

dirty file page

转自:https://www.cnblogs.com/zhiminyu/p/17330763.html 0.前言 Linux 内核Page Cache 和Buffer Cache 关系及演化历史 一文中讲过Linux 2.4之后将Page Cache和Buffer Cache 进行了融合,在buffer_head 中添加了b_page,很容易就能找到缓存的…...

HTAP(Hybrid Transactional/Analytical Processing)系统之统一存储的实时之道

文章目录 HTAP与时俱进LASER中的存储关键知识LSM(Log-Structured Merge Tree)SkipList(跳表)CDC(Changed Data Capture)SST(Sorted Sequence Table) 特性列组(Column Gro…...

【linux】tcpdump 使用

tcpdump 是一个强大的网络分析工具,可以在 UNIX 和类 UNIX 系统上使用,用于捕获和分析网络流量。它允许用户截取和显示发送或接收过网络的 TCP/IP 和其他数据包。 一、安装 tcpdump 通常是默认安装在大多数 Linux 发行版中的。如果未安装,可…...

数字图像处理常用算法的原理和代码实现详解

本专栏详细地分析了常用图像处理算法的数学原理、实现步骤。配有matlab或C实现代码,并对代码进行了详细的注释。最后,对算法的效果进行了测试。相信通过这个专栏,你可以对这些算法的原理及实现有深入的理解!   如有疑问&#xf…...

Pandas实战100例 | 案例 26: 检测异常值

案例 26: 检测异常值 知识点讲解 在数据分析中,检测和处理异常值(或离群值)是一个重要的步骤。异常值可能会影响数据的整体分析。一种常用的方法是使用四分位数和四分位数间距(IQR)来识别异常值。 四分位数和 IQR: …...

C语言学习NO.11-字符函数strlen,strlen函数的使用,与三种strlen函数的模拟实现

&#xff08;一&#xff09;strlen函数的使用 strlen函数的演示 #include <stdio.h> #include <string.h>int main() {char arr1[] "abcdef";char arr2[] "good";printf("arr1 %d,arr2 %d",strlen(arr1),strlen(arr2));return …...

Vue3+ts获取props的值并且定义props值的类型的方法。

1.引入withDefaults模块&#xff0c;给defineProps绑定默认值。 import { withDefaults } from vue2.定义Props传输值的类型。 interface Props {// 类型type: string;name: string;id: number; }3.给props的值设置默认值。 const props withDefaults(defineProps<Prop…...

EasyExcel 不使用科学计数发并以千分位展示

EasyExcel 不使用科学计数发并以千分位展示 不使用科学计数法 不使用科学计数法 BigDecimalStringConverter 将 BigDecimal 类型的数值转换为字符串类型&#xff0c;并将其导出到 Excel 文件中。在 convertToExcelData 方法中&#xff0c;我们将 BigDecimal 转换为字符串&…...

【Python机器学习】SVM——调参

下面是支持向量机一个二维二分类数据集的训练结果&#xff1a; import mglearn import matplotlib.pyplot as plt from sklearn.svm import SVCplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False X,ymglearn.tools.make_handcrafted_dataset()…...

网络传输(TCP)

前言 我们tcpdump抓包时会看到除报文数据外&#xff0c;前面还有一段其他的数据&#xff0c;这段数据分为两部分&#xff0c;ip包头&#xff08;一般20字节&#xff09;和tcp包头&#xff08;一般20字节&#xff09;&#xff0c;一般这两个头长度和为40&#xff0c;我们直接跳…...

MFC模拟消息发送,自定义以及系统消息

在MFC框架下&#xff0c;有很多系统已经定义好的消息&#xff0c;例如ON_WM_LBUTTONDOWN()、ON_WM_MBUTTONDOWN()等等。我们在使用的时候只需要声明并调用就可以了&#xff0c;最简单的用法。 提升了一点难度的用法就是自己设置自定义消息&#xff0c;再提升一点难度的就是如何…...

并发,并行,线程与UI操作

并行和并发是计算机领域中两个相关但不同的概念。 并行&#xff08;Parallel&#xff09;指的是同时执行多个任务或操作&#xff0c;它依赖于具有多个处理单元的系统。在并行计算中&#xff0c;任务被分成多个子任务&#xff0c;并且这些子任务可以同时在不同的处理单元上执行…...

react 6种方式编写样式

在React中&#xff0c;编写样式主要有以下几种方式&#xff1a; 1. 内联样式&#xff1a; 直接在React组件中使用style属性来定义样式。这种方式比较适合定义动态的样式&#xff0c;因为它允许你将JavaScript表达式作为样式的值。 2. 外部样式表 &#xff1a;通过创建外部的…...

计算机找不到msvcr100.dll的多种解决方法分享,轻松解决dll问题

msvcr100.dll作为系统运行过程中不可或缺的一部分&#xff0c;它的主要功能在于提供必要的运行时支持&#xff0c;确保相关应用程序能够顺利完成编译和执行。因此&#xff0c;当操作系统或应用程序在运行阶段搜索不到该文件时&#xff0c;自然会导致各类依赖于它的代码无法正常…...

系分笔记数据库反规范化、SQL语句和大数据

文章目录 1、概要2、反规范化3、大数据4、SQL语句5、总结 1、概要 数据库设计是考试重点&#xff0c;常考和必考内容&#xff0c;本篇主要记录了知识点&#xff1a;反规范化、SQL语句及大数据。 2、反规范化 数据库遵循范式的设计&#xff0c;使得多表查询和连接表查询较多的时…...

php实现支付宝商户转账

目录 一&#xff1a;背景介绍 一&#xff1a;准备工作 三&#xff1a;代码实现 一&#xff1a;背景介绍 最近工作中&#xff0c;要用到支付宝的商家转账功能&#xff0c;用php代码实现&#xff0c;网上找的内容&#xff0c;有些是老版本的实现&#xff0c;有些是调用sdk&am…...

并发编程(十一)

性能测试的常用命令 1、Netstat是在内核中访问网络连接状态及其相关信息的程序&#xff0c;它能够显示协议统计和当前TCP/IP的网络连接。 Netstat命令的常用格式如下&#xff1a; netstat -a&#xff1a;显示所有网络连接和侦听端口。 netstat -b&#xff1a;显示在创建网络…...

vue3 指令详解

系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录前言一、v-model &#xff08;双向绑定功能&#xff09;二、v-bind(用于将一个或多个属性绑定到元素的属性或组件的 prop)三、v-if、v-else、v-else-if(用于根据条件选择性地渲染元素)四、v-show&#xff08;根…...

数据科学竞赛平台推荐

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…...

安全防御之安全审计技术

安全防御中的安全审计技术是保障信息系统安全的重要手段之一。其主要目标是对信息系统及其活动进行记录、审查和评估&#xff0c;以确保系统符合安全策略、法规要求&#xff0c;并能够及时发现潜在的安全风险和异常行为。通过安全审计&#xff0c;可以对系统中的各种活动进行记…...

告别广告侵扰:AdGuard广告拦截扩展全平台部署指南

告别广告侵扰&#xff1a;AdGuard广告拦截扩展全平台部署指南 【免费下载链接】AdguardBrowserExtension AdGuard browser extension 项目地址: https://gitcode.com/gh_mirrors/ad/AdguardBrowserExtension 副标题&#xff1a;从新手到高手的一站式配置方案 一、价值定…...

IBM System/4 Pi:航空航天计算机的兴衰与技术传奇

【导语&#xff1a;1981 年航天飞机首飞&#xff0c;其发射和大部分飞行环节由 IBM 的 System/4 Pi 系列 AP - 101B 计算机控制。该系列于 1967 年推出&#xff0c;广泛应用于航空航天等领域&#xff0c;虽发挥重要作用&#xff0c;但相关信息却较难获取。】System/4 Pi&#x…...

EverythingPowerToys自定义程序集成:扩展外部应用打开方式的完整教程

EverythingPowerToys自定义程序集成&#xff1a;扩展外部应用打开方式的完整教程 【免费下载链接】EverythingPowerToys Everything search plugin for PowerToys Run 项目地址: https://gitcode.com/gh_mirrors/ev/EverythingPowerToys EverythingPowerToys是一款强大的…...

3个关键步骤让LyricsX成为你的Mac音乐伴侣:从基础到精通

3个关键步骤让LyricsX成为你的Mac音乐伴侣&#xff1a;从基础到精通 【免费下载链接】LyricsX &#x1f3b6; Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX LyricsX是一款专为macOS设计的歌词工具&#xff0c;能够智能同步显示…...

Qwen3字幕系统参数详解:对齐窗口大小、置信度阈值、后处理规则

Qwen3字幕系统参数详解&#xff1a;对齐窗口大小、置信度阈值、后处理规则 1. 系统概述与核心价值 清音刻墨是基于通义千问Qwen3-ForcedAligner核心技术的高精度音视频字幕生成平台。这个系统能够像经验丰富的"司辰官"一样&#xff0c;精确捕捉发音的每一个毫秒&am…...

避坑指南:从Paraformer到SenseVoice,语音模型训练数据准备的5个常见错误

避坑指南&#xff1a;从Paraformer到SenseVoice&#xff0c;语音模型训练数据准备的5个常见错误 语音识别和多模态语音模型正在重塑人机交互的边界。当Paraformer凭借其简洁的音频-文本配对要求成为ASR领域的新宠时&#xff0c;SenseVoice却以情感识别、事件标记等多维度分析能…...

CosyVoice3在CSDN星图一键部署:开箱即用,无需复杂配置

CosyVoice3在CSDN星图一键部署&#xff1a;开箱即用&#xff0c;无需复杂配置 1. 引言&#xff1a;语音克隆技术的新选择 你是否曾经想过&#xff0c;只需几秒钟的录音就能让AI完美复刻你的声音&#xff1f;或者为你的视频内容添加多种方言配音&#xff1f;CosyVoice3作为阿里…...

SpringBoot整合ANIMATEDIFF PRO:企业级API网关设计

SpringBoot整合ANIMATEDIFF PRO&#xff1a;企业级API网关设计 动画生成服务在企业级应用中面临高并发挑战&#xff0c;如何构建稳定可靠的API网关成为关键问题 1. 企业级动画生成服务的挑战与需求 在现代企业应用中&#xff0c;AI动画生成服务已经成为内容创作、营销推广、教…...

Android开发者必看:知乎Matisse图片选择器实战教程(附Glide/Picasso配置对比)

Android图片选择器深度实战&#xff1a;Matisse与Glide/Picasso的终极配置指南 每次看到微信那个丝滑的图片选择界面&#xff0c;你是不是也想过在自己的App里实现类似效果&#xff1f;作为知乎开源的明星项目&#xff0c;Matisse确实能帮你快速搭建专业级图片选择功能。但真正…...

ArcPy 脚本:批量生成郑州市 1990-2019 年空间分析结果(核密度、热点、平均中心、标准差椭圆)

ArcPy 脚本&#xff1a;批量生成郑州市 1990-2019 年空间分析结果&#xff08;核密度、热点、平均中心、标准差椭圆&#xff09;背景介绍在城市研究中&#xff0c;我们常常需要分析多年数据的空间分布模式&#xff0c;比如建筑物高度在郑州市的聚集情况、热点区域变化、整体中心…...