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

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

3天内不再提示

让我们一起来探索反向映射这个知识点

Linux阅码场 来源:Linuxer 作者:Linuxer 2020-09-18 10:31 次阅读

反向映射的目的是为了找到所有映射到某一个页面的页表项,从而可以对目标页做一些操作,比如切断映射。

反向映射一直是一个非常神奇的存在,今天我们就好好探索一下这个知识点。

创建

在反向匿名映射中除了page struct,一共有三个相关的数据结构:

vm_area_struct

anon_vma

anon_vma_chain

第一个数据结构我们已经见过了,是一个老朋友。而后两者就是为了构造反向匿名映射而新生的。我们先来看看这两个新的数据结构的样子。

anon_vma

anon_vma +----------------------------+ |root | = self |parent | = self | (struct anon_vma*) | |refcount | = 1 | (atomic_t) | |degree | = 1 | (unsigned) | +----------------------------+

这个结构由anon_vma_alloc()函数统一生成,上图中也显示了创造出来时候的样子。从这里看,也就是个带有上下级关系的这么一个结构。

anon_vma_chain

anon_vma_chain +----------------------------+ |vma | | (struct vm_area_struct*)| |anon_vma | | (struct anon_vma*) | | | |rb | | (struct rb_node) | |same_vma | | (struct list_head) | +----------------------------+

这个结构由anon_vma_chain_alloc()统一创建,貌似创建完了也不需要初始化,拿来后面就直接用了。

组合

到这里,大家应该感觉怪怪的,都不知道这些东西是个啥。别急,我把这些东西组合起来,可能你就会有一些感觉了。

在这里,我们把这三个重要的数据结构之间的组合关系展现给大家。当然这只是最简单的组合关系,目的是为了让大家能有一个感性的认识。

anon_vma_chain链接了anon_vma和vma

vma则会有指针指向自己的anon_vma

空口无凭,眼见为实。那为什么会长成这样的呢?接下来我们就来看看在内核中我们是如何将这些数据结构链接起来的。

链接

上一节的最后,我们看到了三个重要的数据结构通过链表和树连接在了一起,这一节我们就来看看他们是怎么连接起来的。

anon_vma_chain_link

往简单了讲,要连接这三个重要的数据结构,都靠一个函数:anon_vma_chain_link(vma, avc, anon_vma)。而这个函数本身简单到令人发指,以至于我能把整个定义给大家展示出来。

static void anon_vma_chain_link(struct vm_area_struct *vma, struct anon_vma_chain *avc, struct anon_vma *anon_vma) { avc->vma = vma; avc->anon_vma = anon_vma; list_add(&avc->same_vma, &vma->anon_vma_chain); anon_vma_interval_tree_insert(avc, &anon_vma->rb_root); }

你对照这上面的图一看,和图上显示的一摸一样没有任何多余的步骤。

但是,关键的但是来了,如果你以为一切就这这么简单,那就too young too simple了啊。

接下来我们将从anon_vma_chain_link函数被调用的关系入手,去看看在实际运行中究竟会演化出什么样的变化来。

do_anonymous_page

首先出场的是函数do_anonymous_page,这个函数是在匿名页缺页中断时会调用的函数。

do_anonymous_page(vmf) __anon_vma_prepare(vma) avc = anon_vma_chain_alloc() anon_vma = find_mergeable_anon_vma(vma) anon_vma = anon_vma_alloc() vma->anon_vma = anon_vma anon_vma_chain_link(vma, avc, anon_vma)

从上面的流程可以看出,当发生缺页中断时,内核会给对应的vma构造anon_vma,并且利用avc去链接这两者。这种可以说是系统中最简单的例子,也是上图中显示的情况。

细心的人可能已经看到了,上面有一种情况是find_mergeable_anon_vma。如果这个函数返回一个可以重用的anon_vma,那么内核就可以利用原有的anon_vma了。此时这个图我们可以画成这样。

....................... ************************* . . * * av v avc v v vma v +-----------+ +-------------+ +-------------+ | |<------------|anon_vma vma|------------>| | | |<- | | | | +-----------+ +-------------+ +-------------+ ^ ^ ^ ^ . . * * . . ************************* . . . . . . ************************* . . * * . avc v v vma v . +-------------+ +-------------+ . ------|anon_vma vma|------------>| | . | | | | . +-------------+ +-------------+ . ^ ^ ^ . . * * ....................... *************************

其实此处我画得不够精确,av 和 avc之间应当是树的关系,而不是现在显示的链表的关系。但是我想意思已经表达清楚,即在一个进程中多个vma可以共享同一个anon_vma作为匿名映射的节点。

anon_vma_fork

看过了在单个进程中的情况,接下来我们来看看创建一个子进程时如何调整这个数据结构。这个过程由anon_vma_fork处理。

anon_vma_fork(vma, pvma) anon_vma_clone(vma, pvma) anon_vma = anon_vma_alloc() avc = anon_vma_chain_alloc() anon_vma->root = pvma->anon_vma->root anon_vma->parent = pvma->anon_vma vma->anon_vma = anon_vma anon_vma_chain_link(vma, avc, anon_vma)

这个函数很有意思,我还真是花了些时间去理解它。最开始有点看不清,所以我干脆退回到最简单的状态,也就是当前进程是根进程的时候。此时我才大致的了解了一点fork时究竟发生了什么。

话不多说,还是用一个图来表达

....................... ************************* . . * * av v avc v v vma v +-----------+ +-------------+ +-------------+ P | |<------------|anon_vma vma|------------>| | | |<----+ | | | | +-----------+ +-------------+ +-------------+ ^ ^ ^ ^ . . * * . . ************************* . . . . . . . . . . ************************* . . * * . avc v v * . +-------------+ * . |anon_vma vma| * . | | * . +-------------+ * . ^ ^ * . . * * ...................... * * * * * * * * ....................... * * . . * * av v avc v v vma v +-----------+ +-------------+ >+-------------+ C1 | |<------------|anon_vma vma|------------>| | | | | | | | +-----------+ +-------------+ +-------------+ ^ ^ ^ ^ . . * * ....................... *************************

P是父进程,C1是他的一个子进程。当发生fork时,page->mapping没有发生改变,所以依然需要能够从父进程的anon_vma上搜索到对应的页表。此时就得在父进程的rb_root树中保留一个子进程的avc。同时子进程又拥有自己的一套anon_vma。

可以说这个真的是非常有意思的。

对了,代码中还有一个函数anon_vma_clone,在这里我就不展开了。留给大家下来思考一下下。

使用

好了,到了这里我们已经拥有了一个非常强悍的武器 – 匿名反向映射。有了他我们就可以指哪打哪了。

内核也已经给我们准备好了扣动这个核武器的板机 – rmap_walk_anon。

rmap_walk_anon(page, rwc, true/false) anon_vma = page_anon_vma(page), get anon_vma from page->mapping pgoff_start = page_to_pgoff(page); return page_to_index(page) pgoff_end = pgoff_start + hpage_nr_pages(page) - 1; anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff_start, pgoff_end) rwc->rmap_one(page, vma, address, rwc->arg) -> do the real work

有了上面的基础知识,我想看这段代码就不难了。还记得上面看到过的那个rb_root么?对了,我们就是沿着这颗红黑树找到的vma,然后再找到了页表。

嗯,一切都感觉这么的完美。

原文标题:图解内存匿名反向映射reverse mapping

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

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

    关注

    2

    文章

    268

    浏览量

    44593
  • AVC
    AVC
    +关注

    关注

    0

    文章

    21

    浏览量

    11031
  • 映射
    +关注

    关注

    0

    文章

    47

    浏览量

    15899

原文标题:图解内存匿名反向映射reverse mapping

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

收藏 人收藏

    相关推荐

    探索分布式 IO 模块网络适配器

    在自动化控制领域,分布式 IO 模块网络总线适配器,也就是耦合器模块,发挥着极为关键的作用。但对于很多非专业人士来说,这个名字听起来既陌生又晦涩。别担心,接下来就让我们一起深入了解它。
    的头像 发表于 02-21 17:05 90次阅读
    <b class='flag-5'>探索</b>分布式 IO 模块网络适配器

    华邦电子安全闪存关键知识点

    黑客攻击?高温考验?驾驶安全?通通没在怕的!1月15日,华邦电子举办了“安全闪存强化车用电子安全性”为主题的线上研讨会。为了让没能参加这场线上研讨会的邦友们也可以清晰 Get 安全闪存关键知识点,邦
    的头像 发表于 02-12 18:15 401次阅读

    总结了8个常见的知识点

    各位朋友,大家好,这里是大话硬件。 周末在家学习是非常好的时间,把以前的东西梳理下,就是非常不错的题目。一起来看看吧~ 1、什么是建立时间和保持时间? 建立时间(Setup Time)是指被采样
    的头像 发表于 01-24 10:08 133次阅读
    总结了8个常见的<b class='flag-5'>知识点</b>

    Aigtek功率放大器应用:电感线圈的知识点分享

    电磁驱动是功率放大器的大基础应用领域,其中我们最常见的就是用功放来驱动电感线圈,那么关于电感线圈的这10大知识点你都知道吗?今天Aigtek安泰电子来给大家介绍下电感线圈的基础
    的头像 发表于 01-07 15:43 222次阅读
    Aigtek功率放大器应用:电感线圈的<b class='flag-5'>知识点</b>分享

    后悔没有早点看到:天线设计中的知识点

    Cat.1 bis R13架构,天线架构精简为单天线架构,去掉了分集接收天线,因此只需要根天线。   知识点: Cat.1 bis相对于Cat.1的区别是,后者为两根天线(根主天线,
    的头像 发表于 12-24 17:11 596次阅读
    后悔没有早点看到:天线设计中的<b class='flag-5'>知识点</b>!

    视觉AI之旅:一起探索 FiftyOne ——第二部分 入门指南

    /journey-into-visual-ai-exploring-fiftyone-together-part-ii-getting-started-14cca5adfcd3     ,前言 上次我们介绍了《视觉AI之旅:一起
    的头像 发表于 12-24 17:00 167次阅读
    视觉AI之旅:<b class='flag-5'>一起</b><b class='flag-5'>探索</b> FiftyOne ——第二部分  入门指南

    接口测试理论、疑问收录与扩展相关知识点

    本文章使用王者荣耀游戏接口、企业微信接口的展示结合理论知识,讲解什么是接口测试、接口测试理论、疑问收录与扩展相关知识点知识学院,快来一起看看吧~
    的头像 发表于 11-15 09:12 436次阅读
    接口测试理论、疑问收录与扩展相关<b class='flag-5'>知识点</b>

    探索蓝牙5.4:让未来连接更近

    到底有哪些亮点和优势?它又将如何改变我们的生活呢?让我们一起来探索下。1、增强的广播功能蓝牙5.4引入了全新的广播功能,支持更高效的广播数
    的头像 发表于 09-10 16:58 1407次阅读
    <b class='flag-5'>探索</b>蓝牙5.4:让未来连接更近<b class='flag-5'>一</b>步

    选2088还是3051?一起来说说TA们的不同~

    作为工业实践中最常用的现场仪表,变送器被广泛应用于各种工业自控环境,涉及水利水电、铁路交通、智能建筑、生产自控、航空航天、石化、油井、电力、船舶、机床、管道等众多行业。今天我们一起来看看「2088压力变送器」、「3051差压变送器」这两款变送器有啥区别?
    的头像 发表于 09-02 10:40 843次阅读
    选2088还是3051?<b class='flag-5'>一起来</b>说说TA们的不同~

    浅谈PUF技术如何保护知识产权

    知识产权保护,PUF技术拥有天然独特的优势,能够提供周全完善的防盗版解决方案,在保护电子产品知识产权领域具有广阔的应用前景。 接下来,让我们一起看看PUF技术是如何保护
    发表于 07-24 09:43

    焊接机器人的崛起:未来工业自动化的领军者!

    随着科技的不断进步,焊接机器人已经成为了现代工业生产中不可或缺的部分。它们以其高效、精准的工作特性,极大地提升了生产效率和焊接质量。以下是关于焊接机器人的15个重要知识点让我们一起来
    的头像 发表于 06-13 10:33 634次阅读
    焊接机器人的崛起:未来工业自动化的领军者!

    模拟电子技术知识点问题总结概览

    给大家分享模拟电子技术知识点问题总结。
    的头像 发表于 05-08 15:16 1278次阅读
    模拟电子技术<b class='flag-5'>知识点</b>问题总结概览

    篇搞定DCS系统相关知识点

    目标。DCS系统广泛应用于各个行业,如化工、电力、制药等。在这些行业中,DCS系统可以实现对生产过程的集中监控和分散控制,提高生产效率和产品质量,降低能耗和减少环境污染,从而保证产品质量,并确保生产过程的安全可靠。 二.DCS系统知识点
    的头像 发表于 03-26 18:40 1102次阅读
    <b class='flag-5'>一</b>篇搞定DCS系统相关<b class='flag-5'>知识点</b>

    CANape 22.0惊艳亮相!全面升级的新特性引领汽车测试技术飞跃!

    系列令人瞩目的重要更新,为汽车测试技术迈上了个新的台阶提供助力。现在,让我们一起来揭开CANape22.0的神秘面纱,探索它的主要更新特性吧!硬件
    的头像 发表于 03-07 08:23 703次阅读
    CANape 22.0惊艳亮相!全面升级的新特性引领汽车测试技术飞跃!

    【量子计算机重构未来 | 阅读体验】第二章关键知识点

    本帖最后由 oxlm_1 于 2024-3-6 23:20 编辑 之所以将第二章单独拿出来,是因为在阅读过程中,发现第二章知识点较多,理解起来比较耗时间。 第二章的主要知识点: 量子
    发表于 03-06 23:17