彩色科技|linux内核写时复制机制源代码解读
转自Linux阅码场
写时复制技术(以下简称COW)是linux内核比较重要的一种机制 , 我们都知道:父进程fork子进程的时候 , 子进程会和父进程会以只读的方式共享所有私有的可写页 , 当有一方将要写的时候会发生COW缺页异常 。 那么究竟COW在linux内核中是如何触发?又是如何处理的呢?我们将在本文中以源代码情景分析的方式来解读神秘的写时COW , 从源代码级别的角度彻底理解它 。
需要说明的是:本文中所分析的内核源码时linux-5.0版本内核 , 使用arm64处理器架构 , 当然此文章发布时linux内核已经是linux-5.8.x , 当你查看最新的内核源码的时候会发现变化并不是很大 。 本文主要会从下面几个方面去分析讨论写时复制:
- fork子进程时内核为COW做了哪些准备
- COW进程是如何触发的
- 内核时怎样处理COW这种缺页异常的
- 匿名页的reuse
kernel/fork.c_do_fork->copy_process->copy_mm当然本文中讨论的是COW , 暂时不详解其他资源共享以及内存资源共享的其他部分(后面的相关文章我们会讨论) , copy_mm总体来说所作的工作是:分配mm_struct结构实例mm , 拷贝父进程的old_mm到mm,创建自己的pgd页全局目录 , 然后会遍历父进程的vma链表为子进程建立vma链表(如代码段 , 数据段等等) , 然后就是比较关键的页的共享 , linux内核为了效率考虑并不是拷贝父进程的所有物理页内容 , 而是通过复制页表来共享这些页 。 而在复制页表的时候 , 内核会判断这个页表条目是完全复制还是修改为只读来为COW缺页做准备 。共享父进程内存资源处理如下:
首先会处理一些页表项不为空但物理页不在内存中的情况(!pte_present(pte)分支)如被swap到交换分区中的页 , 接下来处理物理页在内存中的情况:
773/*774|* If it's a COW mapping, write protect it both775|* in the parent and the child776|*/777if (is_cow_mapping(vm_flags) //设置父进程页表项为只读779pte = pte_wrprotect(pte); //为子进程设置只读的页表项值780}781上面的代码块是判断当前页所在的vma是否是私有可写的属性而且父进程页表项是可写:247 static inline bool is_cow_mapping(vm_flags_t flags)248 {249return (flags250 }如果判断成立说明是COW的映射 , 则需要将父子进程页表修改为只读:ptep_set_wrprotect(src_mm, addr, src_pte)将父进程的页表项修改为只读 ,pte = pte_wrprotect(pte)将子进程的即将写入的页表项值修改为只读(注意:修改之前pte为父进程原来的pte值 , 修改之后子进程pte还没有写入到对应的页表项条目中!)
修改页表项为只读的核心函数为:
152 static inline pte_t pte_wrprotect(pte_t pte)153 {154pte = clear_pte_bit(pte, __pgprot(PTE_WRITE));//清可写位155pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));//置位只读位156return pte;157 再次回到copy_one_pte函数往下分析:上面我们已经修改了父进程的页表项 , 也获得了子进程即将写入的页表项值pte(注意:现在还没有写入到子进程的页表项中 , 因为此时子进程的页表项值还没有被完全拼接号好) , 接下来我们将要拼接子进程的页表项的值:
782/*783|* If it's a shared mapping, mark it clean in784|* the child785|*/786if (vm_flags //设置页表项值为clean788pte = pte_mkold(pte); //设置页表项值为未被访问过即是清PTE_AF789790page = vm_normal_page(vma, addr, pte); //获得pte对应的page结构(即是和父进程共享的页描述符)791if (page) {792get_page(page);//增进page结构的引用计数793page_dup_rmap(page, false);//注意:不是拷贝rmap 而是增加page->_mapcount计数(页被映射计数)794rss[mm_counter(page)]++;795} else if (pte_devmap(pte)) {796page = pte_page(pte);797798/*799|* Cache coherent device memory behave like regular page and800|* not like persistent memory page. For more informations see801|* MEMORY_DEVICE_CACHE_COHERENT in memory_hotplug.h802|*/803if (is_device_public_page(page)) {804get_page(page);805page_dup_rmap(page, false);806rss[mm_counter(page)]++;807}808}809810 out_set_pte:811set_pte_at(dst_mm, addr, dst_pte, pte);//将拼接的页表项值写入到子进程的页表项中812return 0;
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 所持股份|万兴科技:公司控股股东、实际控制人吴太兵质押150万股
- 发布公告|数量过半!博创科技:天通股份累计减持约150万股
- 英雄科技聊数码|蔡崇信有实力买下篮网,那身价3200亿的马云,能买下几支NBA球队
- 科技前沿阵地|涨疯了!海思安防芯片遭哄抬“围剿”
- 月影浓|吴亦凡机械造型走秀 垫肩披风搭银框眼镜科技感足
- 中国历史发展过程|中国历史发展过程.中国的科技史界过去半个多世纪
- 天津|桂发祥:不再持有昆汀科技股份
- 消费|减持!天通股份:减持博创科技约32万股
- 处罚|老周侃股:吉鑫科技大股东应补偿踩雷投资者
- 华中科技大学|杯具!超本科线95分,本科有路不走,却梦幻般碰瓷,撞开专科的门
