0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核反向映射基础知识详解

Linux阅码场 来源:Linuxer 作者:Linuxer 2020-11-26 14:42 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作者简介

Cheetah,曾为U-boot社区和Linux内核社区提交过若干补丁,主要从事Linux相关系统软件开发工作,负责Soc芯片BringUp及系统软件开发,喜欢阅读内核源代码,在不断的学习和工作中深入理解内存管理,进程调度,文件系统,设备驱动等内核子系统。

为了系统的安全性,Linux内核将各个用户进程运行在各自独立的虚拟地址空间,用户进程之间通过虚拟地址空间相互隔离,不能相互访问,一个进程的奔溃不会影响到整个系统的异常也不会干扰到系统以及其他进程运行。

Linux内核可以通过共享内存的方式为系统节省大量内存,例如fork子进程的时候,父子进程通过只读的方式共享所有的私有页面。再比如通过IPC共享内存方式,各个不相干的进程直接可以共享一块物理内存等等。

我们都知道操作系统开启mmu之后cpu访问到的都是虚拟地址,当cpu访问一个虚拟地址的时候需要通过mmu将虚拟地址转化为物理地址,这叫做正向映射。而与本文相关的是反向映射,它主要是通过物理页来找到共享这个页的所有的vma对应的页表项,这是本文讨论的问题。

本文目录:
1.反向映射的发展
2.反向映射应用场景
3.匿名页的反向映射
4.文件页的反向映射
5.ksm页的反向映射
5.总结

注:反向映射机制是Linux内核虚拟内存管理的难点也是理解内存管理的关键技术之一!!

1.反向映射的发展

实际上在早期的Linux内核版本中是没有反向映射的这个概念的,那个时候为了找到一个物理页面对应的页表项就需要遍历系统中所有的mm组成的链表,然后对于每一个mm再遍历每一个vma,然后查看这个vma是否映射了这页,这个过程极其漫长而低效,有的时候不得不遍历完所有的mm然后才能找映射到这个页的所有pte。

后来人们发现了这个问题,就再描述物理页面的page结构体中增加一个指针的方式来解决,通过这个指针来找到一个描述映射这个页的所有pte的数组结构,这对于反向映射查找所有pte易如反掌,但是带来的是浪费内存的问题。

接着就在2.6内核的时候,内核大神们想到了复用page结构中的mapping字段,然后通过红黑树的方式来组织所有映射这个页的vma,形成了匿名页和文件页的反向映射机制。

如下为匿名页反向映射图解:

如下为文件页反向映射图解:

但是后来匿名页的反向映射遇到了效率和锁竞争激烈问题,就促使了目前使用的通过avc的方式联系各层级反向映射结构然后将锁的粒度降低的这种方式。可以看到反向映射的发展是伴随着Linux内核的发展而发展,是一个不断进行优化演进的过程。

2.反向映射应用场景

那么为何在Linux内核中需要反向映射这种机制呢?它究竟为了解决什么样的问题而产生的呢?

试想有如下场景:
(1)一个物理页面被多个进程的vma所映射,系统过程中发生了内存不足,需要回收一些页面,正好发现这个页面是适合我们回收利用的,我们能够直接把这个页面还给伙伴系统吗?答案肯定是不能。因为这个页面被很多个进程所共享,我们必须做的事情就是断开这个页面的所以映射关系,这就是反向映射所做的事情。
(2)一些情况我们需要将一个页面迁移到另一个页面,但是牵一发而动全身,可能有一些进程已经映射这个即将要迁移的页面到自己的vma中,那么这个时候同样需要我们知道究竟这个页面被哪些vma所映射呢?这同样是反向映射所做的事情。

实际上,反向映射的主要应用场景为内存回收和页面迁移,当系统发生内存回收和页面迁移的时候,对于每一个候选页Linux内核都会判断是否为映射页,如果是,就会调用try_to_unmap 来解除页表映射关系,本文也主要来从try_to_unmap函数来解读反向映射机制。

如果我们在细致到其他的内核子系统会发现,在内存回收,内存碎片整理,CMA, 巨型页,页迁移等各个场景中都能发现反向映射所做的关键性的工作,所有理解反向映射机制在Linux内核中的实现是理解掌握这些子系统的基础和关键性所在,否则你即将不能理解这些技术背后的脊髓所在,所以说理解反向映射这种机制对于理解Linux内核内存管理是至关重要的!!!

3.匿名页的反向映射

匿名页的共享主要发生在父进程fork子进程的时候,父fork子进程时,会复制所有vma给子进程,并通过调用dup_mmap->anon_vma_fork建立子进程的rmap以及和长辈进程rmap关系结构:


主要通过anon_vma这个数据结构体中的红黑树将共享父进程的页的所有子进程的vma联系起来(通过anon_vma_chain 来联系对应的vma和av),当然这个关系建立比较复杂,涉及到vma,avc和av这些数据结构体。.

而在缺页异常do_anonymous_page的时候将page和vma相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_anon ->anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root,pgoff_start, pgoff_end) ->rwc->rmap_one ->try_to_unmap_one

对于候选页,会拿到候选页相关联的anon_vma,然后从anon_vma的红黑树中遍历到所有共享这个页的vma,然后对于每一个vma通过try_to_unmap_one来处理相对应的页表项,将映射关系解除。

4.文件页的反向映射

文件页的共享主要发生在多个进程共享libc库,同一个库文件可以只需要读取到page cache一次,然后通过各个进程的页表映射到各个进程的vma中。

管理共享文件页的所以vma是通过address_space的区间树来管理,在mmap或者fork的时候将vma加入到这颗区间树中:


发生文件映射缺页异常的时候,将page和address_space相关联。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_file ->vma_interval_tree_foreach(vma, &mapping>i_mmap,pgoff_start, pgoff_end) ->rwc->rmap_one

对于每一个候选的文件页,如果是映射页,就会遍历page所对应的address_space的区间树,对于每一个满足条件的vma,调用try_to_unmap_one来找到pte并解除映射关系。

5.ksm页的反向映射

ksm机制是内核将页面内容完全相同的页面进行合并(ksm管理的都是匿名页),将映射到这个页面的页表项标记为只读,然后释放掉原来的页表,来达到节省大量内存的目的,这对于host中开多个虚拟机的应用场景非常有用。

ksm机制中会管理两课红黑树,一棵是stable tree,一棵是unstable tree,stable tree中的每个节点stable_node中管理的页面都是页面内容完全相同的页面(被叫做kpage),共享kpage的页面的页表项都会标记为只读,而且对于原来的候选页都会有rmap_item来描述他的反向映射(其中的anon_vma成员的红黑树是描述映射这个候选页的所有vma的集合),合并的时候会加入到对应的stable tree节点和链表中。

当内存回收或页面迁移的时候,内核路径最终会调用到:

try_to_unmap //mm/rmap.c ->rmap_walk ->rmap_walk_ksm //mm/ksm.c -> hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) ->anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,0, ULONG_MAX) ->rwc->rmap_one

对于一个ksm页面,反向映射的时候,会拿到ksm页面对应的节点,然后遍历节点的hlist链表,拿到每一个anon_vma,然后就和上面介绍的匿名页的反向映射一样了,从anon_vma的红黑树中找到所有的vma,最后try_to_unmap_one来找到pte并解除映射关系。

6.总结

前面我们介绍了反向映射的三种类型,匿名页,文件页和ksm页的反向映射,分别通过page所对应的的vma, address_space, stable_node结构来查找vma。当然我们只是介绍了Linux内核中的反向映射的冰山一角,主要是try_to_unmap函数,其实每种反向映射各个数据结构建立的过程错综复杂,一篇文章三言两语也说不清楚,他们散落在Linux内核源代码的进程创建fork,内存映射mmap,缺页异常处理,文件系统等各个角落。

诚然,如果我们搞不清楚各种反正映射所对应的各种数据结构之间的关系,或者只是有一些概念上的了解,并没有真正掌握这种机制的实现原理,对于我们来理解Linux内核虚拟内存管理来说是一种障碍,不懂得反向映射内存管理 中的很多问题是搞不明白的!

责任编辑:PSY

原文标题:深入剖析Linux内核反向映射机制

文章出处:【微信公众号:Linuxer】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 映射
    +关注

    关注

    0

    文章

    49

    浏览量

    16433
  • LINUX内核
    +关注

    关注

    1

    文章

    318

    浏览量

    23051
  • 反向
    +关注

    关注

    0

    文章

    7

    浏览量

    7601

原文标题:深入剖析Linux内核反向映射机制

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux驱动开发的必备知识

    内核基础知识: 1、熟悉 Linux 内核的架构、模块系统、进程管理、内存管理等。 了解内核的编译和加载过程。 2、C编程技能: 精
    发表于 12-04 07:58

    【迅为工业RK3568稳定可靠】itop-3568开发板Linux驱动开发实战:RK3568内核模块符号导出详解

    【迅为工业RK3568稳定可靠】itop-3568开发板Linux驱动开发实战:RK3568内核模块符号导出详解
    的头像 发表于 11-21 13:25 653次阅读
    【迅为工业RK3568稳定可靠】itop-3568开发板<b class='flag-5'>Linux</b>驱动开发实战:RK3568<b class='flag-5'>内核</b>模块符号导出<b class='flag-5'>详解</b>

    【书籍评测活动NO.67】成为硬核Linux开发者:《Linux 设备驱动开发(第 2 版)》

    ——这便是《Linux 设备驱动开发》。本书从基础知识出发,分专题透彻讲解Linux环境下的设备驱动开发知识,帮助读者从零构建驱动程序。如今4年过去,作者紧跟技术发展,对内容进行了大量
    发表于 11-17 17:52

    视觉工程师必须知道的工业相机基础知识

    工业相机基础知识概述。
    的头像 发表于 09-19 17:04 886次阅读
    视觉工程师必须知道的工业相机<b class='flag-5'>基础知识</b>

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 785次阅读

    效果器的基础知识

    电子发烧友网站提供《效果器的基础知识.doc》资料免费下载
    发表于 03-26 14:30 6次下载

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    引言本文是对我之前关于RaspberryPi3同一主题的帖子的更新。与之前的帖子一样,我使用的是随Raspbian镜像提供的标准内核,以及应用了RT补丁的相似内核版本。对于实时版,我
    的头像 发表于 03-25 09:39 656次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    开关电源的基础知识题目及答案(免积分)

    本文含有开关电源的基础知识题目及答案,下载附件即可查看!
    发表于 03-06 15:52

    功率器件热设计基础知识

    功率器件热设计是实现IGBT、碳化硅SiC等高功率密度器件可靠运行的基础。掌握功率半导体的热设计基础知识,不仅有助于提高功率器件的利用率和系统可靠性,还能有效降低系统成本。本文将从热设计的基本概念、散热形式、热阻与导热系数、功率模块的结构和热阻分析等方面,对功率器件热设计基础知识
    的头像 发表于 02-03 14:17 1253次阅读

    PCB绘制基础知识

    电子发烧友网站提供《PCB绘制基础知识.pdf》资料免费下载
    发表于 01-21 15:20 8次下载
    PCB绘制<b class='flag-5'>基础知识</b>

    EMC基础知识-华为

    EMC基础知识-华为
    发表于 01-06 14:09 5次下载

    腾讯云内核团队修复Linux关键Bug

    腾讯云操作系统(Tencent OS)内核团队近日在Linux社区取得了显著成果。他们提交的两项改进方案,成功解决了自2021年以来一直困扰众多一线厂商,并在近期让多个Linux顶级
    的头像 发表于 12-31 10:58 915次阅读

    万字长文,看懂激光基础知识

    深入介绍激光基础知识,帮助您轻松理解激光领域的关键概念和原理。
    的头像 发表于 12-20 09:49 2101次阅读
    万字长文,看懂激光<b class='flag-5'>基础知识</b>!

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    学到本章节,大家应该对Linux操作系统都有了一定的了解,但可能还不知道我们拿到手的内核源码都经历了什么。linux有一个庞大的开源社区,每个人都可以向开源社区提交代码。由于linux
    发表于 12-13 09:03

    华为-射频基础知识培训

    课程目标z 熟悉和掌握射频基本概念和知识z 了解无线射频系统结构z 了解天馈系统的概念和知课程内容第一章 无线通信的基本概念第二章 射频常用计算单位简介第三章 射频常用概念辨析第四章 射频系统介绍第五章 天线传播基础知识简介
    发表于 12-10 13:39 1次下载