首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux内核写时复制机制源代码解读

写时复制技术(一下简称COW)是linux内核比较重要的一种机制,我们都知道:父进程fork子进程的时候,子进程会和父进程会以只读的方式共享所有私有的可写,当有一方将要写的时候会发生COW缺页异常。...(src_mm, addr, src_pte)将父进程的表项修改为只读, pte = pte_wrprotect(pte)将子进程的即将写入的表项值修改为只读(注意:修改之前pte为父进程原来的pte...entry = pte_mkdirty(entry); 3804 } 程序走到上面的判断说明:表项存在,物理存在内存,但是vma是可写,pte表项只读属性(这就是fork的时候所作的准备...2291 cache中刷新页 2292行 由vma的访问权限和新页的描述符来构建表项的值 2293行 设置表项值属性为脏和可写(如果vma有可写属性,这个时候将表项修改为了可写,fork的时候修改为只读这个地方修改了回来...,并将父子进程对应的表项修改为只读,当有一方试图写共享的物理,由于表项属性是只读的会发生COW缺页异常,缺页异常处理程序会为写操作的一方分配新的物理,并将原来共享的物理内容拷贝到新页,然后建立新页的表映射关系

4.6K20
您找到你想要的搜索结果了吗?
是的
没有找到

深入理解Linux内核之脏跟踪

Linux内核中,因为跟踪脏会涉及到文件回写、缺页异常、反向映射等技术,所以本文也重点讲解在Linux内核中如何跟踪脏。...3)脏回写时,会通过反向映射机制,查找映射这个的每一个vma, 设置相应进程的表项只读,清脏标记。...因为表项只读,所以写访问会发生写时复制缺页异常,异常处理中将处理共享文件映射,重新将相应进程的表项为设置为脏、可写。...这时可以直接写访问文件,不会发生缺页。 2)脏已经回写时(确切的说是调用clear_page_dirty_for_io之后),描述符已经清除了脏标记,表项已经清除了脏标记,且只读。...,回写之前(clear_page_dirty_for_io完成之前),表项的脏标志是置位的,回写的时候(clear_page_dirty_for_io的调用)会通过反向映射机制将所有映射这个表项的脏标志位清零并设置只读权限

2K10

深入理解反向映射

作者:Cheetah老师一直从业于半导体行业,他曾为U-boot社区和Linux内核社区提交过若干补丁。...在迁移页面的时候,如果是映射,会调用try_to_unmap将映射这个物理的每个表项修改为迁移类型表项。...图:反向映射应用之脏跟踪(1) 图:反向映射应用之脏跟踪(2) 第三个场景是脏跟踪,对于共享的文件,由于文件被多个进程共享,linux内核通过表项的“脏”标记跟踪页面为脏。...每一次回写时,都会调用clear_page_dirty_for_io函数,这个函数会通过反向映射将映射这个页面的每个表项都修改为只读并清脏标记。...再次访问时,发生写实复制缺页异常,异常处理中再次设置表项为脏、可写,从而跟踪了脏。 图:反向映射应用场景之访问跟踪 还有个场景是访问跟踪,linux内核通过表项的“访问”标记跟踪页面被访问。

1.1K20

操作系统段结合的实际内存管理--13

, 设置为只读 *to_page_table = this_page; //将源表项存进目的表项 if (this_page...也就是说,只有对于非内核地址空间的页面,才会将被fork共享的页面所对应的表项设为只读,从而在最后一次写操作的时候,将源页面释放。...而对于内核地址空间的地址共享,只将进程1的目录的属性设置为只读,而源目录表项(进程0)依然是可读写的。...//如果是主内存区 *from_page_table = this_page;//源表项也要设置为只读 this_page -=...,但是对应的表项只读的,因此进程产生一次写保护错误,内核将给进程分配一个新的物理页面,将共享页面的内容复制过来,新的页面将设置为可读写,而共享页面仍然是只读的。

74420

Linux 标准大和透明大

Huge pages ( 标准大 ) 和 Transparent Huge pages( 透明大 ) 在 Linux 中大分为两种:Huge pages ( 标准大 ) 和 Transparent...内存是以块即的方式进行管理的,当前大部分系统默认的大小为 4096 bytes 即 4K。1MB 内存等于 256 ;1GB 内存等于 256000 。...Huge Pages Huge pages 是从 Linux Kernel 2.6 后被引入的,目的是通过使用大内存来取代传统的 4kb 内存页面, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能...Transparent Huge Pages Transparent Huge Pages 缩写 THP ,这个是 RHEL 6 开始引入的一个功能,在 Linux6 上透明大是默认启用的。...No Swapping: We must avoidswapping to happen on Linux OS at all Document 1295478.1.

4.8K50

Linux下访问匿名发生的神奇“化学反应”

Linux中有后备文件支持的称为文件,如属于进程的代码段、数据段的,内存回收的时候这些页面只需要做脏的同步即可(干净的页面可以直接丢弃掉)。...2.内核原理 下面我们从Linux内核的层面来解析发生以上神奇现象的原理。...5标签处:通过发生缺页的虚拟地址来计算出表项的地址保存在 vmf->pte。 最11标签处:将4标签初组合出的表项的值写入到5标签初计算出的表项中。...在2标签处判断表项的属性是否是只读。在3标签处进行实际的写时复制处理。...4)第一次读匿名后,然后写匿名,先只读方式映射到0,然后发生写时复制,分配物理,虚拟以可读可写的方式映射到此物理

57210

合法修改只读数据

也可以发现编译器将.text和.rodata 放在一个段中,然后用一个程序头表项来描述,段的类型为load(需要加载到进程地址空间), Flags为只读可执行。...这里当我们写只读数据的时候,即是执行buf[0] = 'a'语句的时候,假如buf[0] 地址所在的虚拟还没有映射物理(没有填写相关表), 那么arm64处理器将发生转换表错误的异常(实际上,如果先读只读数据...,就像代码中写那样,那么就首先建立了只读数据的虚拟和物理表映射,然后再次进程写访问的时候,就会发生访问权限错误的异常),将进入linux内核的异常处理的路径中: el0_sync //arch...合法修改只读数据 上面几节我们详细分析了,修改只读数据为何发生段错误的过程和原因,那么下面我们就想合法修改只读数据怎么办,我们直观上知道需要修改只读数据的表属性为可写,但是需要在改写表之前需要保证表已经存在...那么我们下面的代码通过两种方式来修改只读数据的表,一种是我们通过访问一个字符设备来修改表(字符设备驱动程序所作的工作就是遍历各级表,然后将相关的叶子表项修改为可写),一种是通过mprotect来实现

1.1K20

解决 Linux 挂载 NTFS 分区只读不能写的问题

有没有小伙伴也是跟我一样电脑上同时装有 Windows 和 Linux 双系统的呢?...但是对于还不太熟悉 Linux 的小伙伴来说,起初总是会踩到各种各样的坑。...平时的时候看看剧打打机啥的就进去 Windows,敲代码做项目的时候就进去 Linux。在 Linux 的时候,就直接挂载 NTFS 格式的那个 D 盘,因为我的代码都在那个盘里。...这时候再回到 Linux 中重新挂载这个 D 盘时,就不会出现只读不能写的情况了。 说到这里,我得唠嗑几句。...这次遇到的坑,其实算不上什么坑,并且我们得承认 Linux 的这个数据保护措施做的很到位,如果我在 Windows 中将电脑休眠了而在 Linux 中还能正常读写的话,那个后果是可想而知的。

9.2K30

Linux内核表管理-那些鲜为人知的秘密

,而表管理是在虚拟内存管理中尤为重要,本文主要以回答几个表管理中关键性问题来解析Linux内核表管理,看一看表管理中那些鲜为人知的秘密。...,造成每个进程都认为自己拥有所有虚拟内存的错觉;通过表给一段内存设置只读属性,那么就不容许修改这段内存内容,从而保护了这段内存不被改写;对应用户进程地址空间映射的物理内存,内核可以很方便的进行页面迁移和页面交换...Linux内核为何使用多级表?...2)Linux内核 填写表,将表基地址告诉mmu 内核初始化建立内核表,实现缺页异常等机制为用户任务按需分配并映射表。 当然,内核也可以遍历表,如缺页异常时遍历进程表。 10....12.表遍历过程 下面以arm64处理器架构多级表遍历作为结束(使用4级表,大小为4K): Linux内核中 可以将表扩展到5级,分别是全局目录(Page Global Directory,

1.7K21

深入理解Linux内核表映射分页机制原理

表的好处: 省内存:可以解决分页机制占用内存的问题,取得和多级表一样节省内存的效果; 对TLB友好:大表意味着地址转换时需要更少的表映射表项表映射表项少了意味着TLB缓存的表项少,这样就提高了...因此,在这里稍微调整了实现—告诉Linux在第一级有2048个条目,每个都是8字节。二级表包含两个连续排列的硬件PTE表项,前面的表项是包含Linux需要的状态信息的Linux PTE。...也就是说ARM表设置时将权限设置为只读,当向页面写入时,会触发缺页异常(Linux PTE页面表项标记了可写权限,但是ARM硬件页面表项只读权限),在缺页异常处理函数handle_pte_fault...,Linux使用的表项即r0所指内存,ARM硬件使用的表项地址是r0+2048。...寄存器r1表示要写入内存的Linux PTE表项的内容,其属性bit位设置均使用L_前缀的宏定义。 第一句语句将Linux PTE设置到r0指向的内存。

2.9K10

Linux 透明大 THP 和标准大 HP

作者 | JiekeXu 大家好,我是JiekeXu,很高兴又和大家见面了,今天和大家一起来看看 Linux 透明大 THP 和标准大 HP 目 录 标准大(HugePages) 透明大(Transparent...在 Linux 中大分为两种: Huge pages (标准大) 和 Transparent Huge pages(透明大)。...标准大(HugePages) 标准大(HugePages)是从 Linux Kernel 2.6 后被引入的,Huge Pages 可以称为大内存或者大页面,有时候也翻译成大/标准大/传统大...透明大存在的问题: Oracle Linux team 在测试的过程中发现,如果 linux 开启透明大 THP,则 I/O 读写性能降低 30%;如果关闭透明大 THP,I/O 读写性能则恢复正常...因此,Oracle 建议在所有 Oracle 数据库服务器上禁用透明大,以避免性能问题。 Linux7 默认情况下是开启透明大功能的。检查系统对应版本。

2.3K20

韦东山:Linux驱动程序基石之mmap

二级表地址旺射的最小单位有4K、1K,Linux使用4K。 一级表项里的内容,决定了它是指向一块物理内存,还是指问二级表,如下图: ?...2.1, 一级表映射过程 一线表中每一个表项用来设置1M的空间,对于32位的系统,虚拟地址空间有4G,4G/1M=4096。所以一级表要映射整个4G空间的话,需要4096个表项。...个1M,所以找到表里第0x123项,根据此项内容知道它是一个段表项。...根据此项内容知道它是一个二级表项。...③ 从这个表项里取出地址,假设是address,这表示的是二级表项的物理地址; ④ vaddr[19:12]表示的是二级表项中的索引index即0x45,在二级表项中找到第0x45项; ⑤ 二级表项中含有基地址

6.9K40

linux中透明巨与巨的区别

Linux中,透明巨(Transparent HugePage)和巨(HugePage)是两种不同的内存管理技术。 透明巨Linux内核中的一项特性,旨在提高内存的利用率和性能。...它通过将内存分配为更大的巨(通常为2MB或1GB),减少了对内存表的访问次数,从而提高了内存访问的效率。透明巨是透明的,应用程序无需进行任何修改即可受益于这种内存管理技术。...而巨是指一种更大尺寸的内存,在Linux中可以使用不同的页面大小,常见的巨大小是2MB或1GB。...巨可以提供更高的内存访问性能,因为它减少了表的数量,降低了TLB(Translation Lookaside Buffer)缓存的压力,从而减少了内存访问的开销。...巨需要应用程序进行适当的修改和配置才能使用。 因此,透明巨和巨都是通过增加内存的尺寸来提高内存访问性能,但透明巨不需要应用程序的修改,而巨需要应用程序的支持和配置。

23610

Linux内核虚拟内存管理之匿名映射缺页异常分析

作者简介 韩传华,就职于南京大鱼半导体有限公司,主要从事linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,乐于分享喜欢学习,喜欢专研Linux内核源代码。...注:本文使用linux-5.0内核源代码。文章分为以下几节内容: 1.匿名映射缺页异常的触发情况 2.0是什么?为什么使用0?...那么我们想知道的时候是什么时候0被设置为了只读属性的(也就是表项何时被设置为只读)? 我们带着这个问题去在内核代码中寻找答案。...所以就将其表设置为了只读!!! 2922行 跳转到setpte去将设置好的表项值填写到表项中。...2928 行会分配一个高端 可迁移的 被0填充的物理。2941 设置中数据有效 2943 使用帧号和vma的访问权限设置表项值(注意:这个时候表项属性依然为只读)。

2.8K32

MIT_6.s081_Lab3:Xv6 and PageTable

)通过在用户空间和内核之间共享只读区域中的数据来加速某些系统调用。...创建每个进程时,在 USYSCALL(memlayout.h 中定义的 VA)映射一个只读页面。...page table 0x0000000087f6e000//二级表 ..0: pte 0x0000000021fda801 pa 0x0000000087f6a000//二级表的表项,进入一级表...首先要确定的第一点就是,这个表其实实际上是一种多级表的结构,就是二级表存储的表项(PPN)其实是一级表的第一个PTE的地址,一级表的表项才是pa.具体的多级表的解释可以参考我其他的博客或者翻阅操作系统或者组员书...所以说这个东西就可以转化为基本的递归.对于二级表,对于每一个表项就进入到一级表再遍历.所以说本质上这就是一个树,二级表作为根,有若干个儿子,也就是一级表,一级表也有若干个儿子…那遍历树怎么遍历

39820

Linux 匿名的反向映射

我们知道LINUX的内存管理系统中有”反向映射“这一说,目的是为了快速去查找出一个特定的物理在哪些进程中被映射到了什么地址,这样如果我们想把这一换出(SWAP),或是迁移(Migrate)的时候,就能相应该更改所有相关进程的表来达到这个目的...1、为什么要使用反向映射   物理内存的分页机制,一个PTE(Page Table Entry)对应一个物理,但一个物理可以由多个PTE与之相对应,当该页要被回收时,Linux2.4的做法是遍历每个进程的所有...Linux采用三级表: PGD:顶级表,由pgd_t项组成的数组,其中第一项指向一个二级表。...PMD:二级表,由pmd_t项组成的数组,其中第一项指向一个三级表(两级处理器没有物理的PMD)。 PTE:是一个对齐的数组,第一项称为一个表项,由pte_t类型表示。...pte_present(*pte)) goto out_unmap; /* 有了pgd pmd pte 后我们便达到我们目的了 ===> 查找与相关联系的表项,找到后便可以进行修改了

3.6K31
领券