缺页异常:

缺页异常(Page Faults)属于ARM V8处理器的异常类型中的同步异常。当MMU走表时可能会产生若干种类型的MMU faults(有同步的也有异步的),其中的同步异常,即这里将要讨论的“缺页异常”。本文将围绕ARM64架构和Linux5.0的代码展开分析。

ARM V8手册中的对缺页异常的描述:

常见场景:

  1. 地址空间映射关系未建立
    1.1:malloc/mmap申请虚拟的地址空间并未分配实际物理页,首次访问触发缺页异常。
  2. 地址空间映射关系已建立
    2.1:要访问的页面已经被swapping到了磁盘,访问时触发缺页异常。
    2.2:fork子进程时,子进程共享父进程的地址空间,写是触发缺页异常(COW技术)。
    2.3:要访问的页面被KSM合并,写时触发缺页异常(COW技术)。
    2.4:兼容的ARM32体系架构模拟PTE_DIRTY PTE_YOUNG比特。
  3. 访问的地址空间不合法
    3.1:用户空间访问内核空间地址,触发缺页异常。
    3.2:内核空间访问用户空间地址,触发缺页异常。(不包括copy_to/from_user的情况)

注:欢迎评论补充 :)

处理缺页异常前的流程:

直接放图,图中大致体现了cpu处于el0和el1等级下,从触发缺页异常到进入do_page_fault之前的流程处理。
代码:arch/arm64/entry.S)

缺页异常前的代码分析:

假设发生的是el0等级下的data abort,代码执行路径为:el0_sync->el0_da->do_mem_abort,el0_sync->el0_da。

主要是为调用do_mem_abort准备三个形参,函数声明如下。

void do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs)

addr:FAR存器中存放的出错地址。
esr: ESR寄存器中记录的MMU fault具体信息。
regs:异常发生时保存的寄存器信息pt_regs。

el0_da:mrs     x26, far_el1        //获取far寄存器中的异常地址enable_daifct_user_exitclear_address_tag x0, x26mov     x1, x25         //获取el0_sync中保存的esr寄存器内容mov     x2, sp          //获取sp指向的pt_regs指针bl      do_mem_abort      //带着三个形参跳入do_mem_abortb       ret_to_user

do_mem_abort() :

do_mem_abort()可以看做错误处理的入口。linux内核为各种同步类型的MMU faults定义了相关的处理函数,并保存在名为fault_info[]的数组中。当发生错误时,do_mem_abort函数会根据ESR寄存器中的错误信息对应到fault_info[]中的处理函数。fault_info[]的定义如下:

static const struct fault_info fault_info[] = {{ do_bad,               SIGKILL, SI_KERNEL,     "ttbr address size fault"       },                                   { do_bad,               SIGKILL, SI_KERNEL,     "level 1 address size fault"    },                                   { do_bad,               SIGKILL, SI_KERNEL,     "level 2 address size fault"    },                                   { do_bad,               SIGKILL, SI_KERNEL,     "level 3 address size fault"    },                                   { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 0 translation fault"     },     el0下发生的translation错误                         { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 1 translation fault"     },     el1下发生的translation错误                              { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 2 translation fault"     },     el2下发生的translation错误                              { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 3 translation fault"     },     el3下发生的translation错误                              { do_bad,               SIGKILL, SI_KERNEL,     "unknown 8"                     },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault"     },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault"     },                                   { do_bad,               SIGKILL, SI_KERNEL,     "unknown 12"                    },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"      },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },                                   { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"      }, ......
}/*此函数逻辑很简单,通过ESR寄存器的内容找到对应的fault_info并执行对应handler*/
asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,      struct pt_regs *regs)
{const struct fault_info *inf = esr_to_fault_info(esr);  //根据esr的值查询fault_info[],其定义了所有的内存异常情况处理。if (!inf->fn(addr, esr, regs))                          //将形参addr和regs传给handler,并执行handlerreturn;                                         //若返回0,代表成功,并直接return。......
}

我们主要关注两个错误处理函数do_translation_fault()和do_page_fault(),do_translation_fault()是处理页表pgd/pud/pmd/pte在转换过程中出现的错误,do_page_fault()是处理访问PTE相关的错误。do_translation_fault()最终仍调用do_page_fault(),所以接下来的代码分析围绕核心函数do_page_fault()。

do_page_fault :

do_page_fault这个函数相对复杂,其中有着大量条件判断,我梳理出下主要几个阶段并画了幅流程图,二者结合起来看会比较清晰。(就不贴冗长的代码了,读者可自行结合代码看)

主要阶段:

阶段1:判断缺页异常是否发生在内核线程或原子上下文中(中断也属于一种原子上下文),是的话执行do_kernel_fault尝试修复或报段错误。

阶段2:判断是否是内核态访问用户地址空间的情况,是的话判断是否是指定的三种情况,是则报段错误。

阶段3:进入_do_page_fault, 查找异常地址所在的vm_area_struct域,并走表(page table walk)查找address对应PGD PUD PMD,最终找到PTE。

阶段4:进入handle_pte_fault(),判断PTE为空的话,说明用户空间申请了虚拟地址后第一次访问,尚未映射物理页面。在根据页面类型分别执行do_anonymous_page或do_fault。

阶段5:PTE非空表示已经建立过映射。判断PTE的present位是否为真,非真说明页面被swapping到磁盘上,随即执行do_swap_page。

阶段6:判断PTE_PROT_NONE是否为真,若为真执行do_numa_page产生页面迁移。

阶段7:判断错误类型,若是写类型的错误,再判断PTE的读写权限。只读的话说明页面是写保护的,调用do_wp_page。

阶段8: 为了兼容ARM32,ARM32体系架构的Hardware PTE中不支持DIRTY YOUNG等bit位,所以通过软件上配合缺页异常进行模拟。

major fault与minor fault:

当我们进行性能分析时,某进程page faults发生的次数也是我们常常要观测的一个指标。但不论是perf、top再或者其他的工具关于page fault发生的次数的输出都会区分为major fault或minor fault两种,它们同为缺页异常,有什么不同呢?

major fault:

  1. user space address触发缺页异常时,若被访问的地址映射的物理页已经被swap到磁盘空间,需要从磁盘中将页面换入。
  2. user space address触发缺页异常时,若被访问的地址空间是被mmap映射到磁盘文件的话且page cache中还未缓存文件内容,需要通过磁盘IO将内容读入page cache。

minor fault:

  1. 当user space address触发缺页异常时,kernel可直接从buddy system中分配出内存用来满足该缺页异常即minor page fault

简单来说,major fault和minor fault的区别就是是否会触发读写磁盘的动作。

原创文章,转载和引用请注明出处。

作者:Yann Xu

模拟请求分页管理中地址转换和缺页中断处理_Linux内存管理:缺页异常(一)相关推荐

  1. 玄铁C910内存管理与地址转换技术

    玄铁C910内存管理与地址转换技术 玄铁 C910 简介 C910 兼容 RISC-V 架构,采用12级超标量流水线,针对算术运算.内存访问以及多核同步等方面进行了优化,同时标配内存管理单元,可运行 ...

  2. Linux内存管理(一)——从硬件角度看内存管理

    从硬件角度看内存管理 ①.在操作系统还没有出来之前,程序都是被存放在卡片上,计算机读取一张卡片就运行一条指令.这种从外部存储介质上直接运行指令的方法效率很低 ②.单道编程的内存管理 所谓单道,就是整个 ...

  3. python的内存管理机制及调优手段_Python的内存管理机制及调优手段?

    转载自 http://kkpattern.github.io/2015/06/20/python-memory-optimization-zh.html 准备工作 为了方便解释Python的内存管理机 ...

  4. Linux内核内存管理:地址转换和MMU

    地址转换和MMU 虚拟内存是一个概念,是给进程的一种错觉,因此它认为自己拥有巨大的.几乎无限的内存,有时甚至比系统实际拥有的内存还要多.每次访问内存位置时,由CPU将虚拟地址转换为物理地址.这种机制称 ...

  5. 计算机技术在档案管理中的应用研究,计算机技术在现代文化档案管理中的应用研究.pdf...

    计算机技术在现代文化档案管理中的应用研究.pdf (1页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 4.9 积分 20 15 年 7 月 第 18 卷第 ...

  6. 计算机在档案管理中的应用,浅谈计算机在档案管理中的应用

    随着计算机技术信息技术迅猛发展和广泛应用,计算机技术为档案信息资源的科学管理和有效开发利用创造了前所未有的契机,信息成为知识经济时代最为重要的资源.目前,档案电子化是档案管理工作必须实施的重要工作,已 ...

  7. 计算机技术在档案管理中的应用,浅谈计算机技术在档案管理中的应用

    [关键词]计算机技术;档案管理;应用 21世纪人类科技发展日新月异,但发展最快.对人类社会影响最深的是计算机技术的发展与应用.计算机技术在档案管理工作中发挥着极其重要的作用.计算机技术在学校档案管理中 ...

  8. 关于python变量使用下列说法中错误的是_关于Python内存管理,下列说法错误的是_学小易找答案...

    [单选题]Python 编程中用代码缩进表示逻辑递进关系,通常用几个空格 [判断题]决定系数(英语:coefficient of determination,记为R2或r2)在统计学中用于度量因变量的 ...

  9. 关于python内存管理下列说法中错误的是_2.关于Python内存管理,下列说法错误的是_学小易找答案...

    [单选题]6.下列表达式的值为True的是 [单选题]2.关于Python内存管理,下列说法错误的是 [单选题]890.具有很强的储存功能,存储空间比较大的配送中心所属的类型是( ) [多选题]109 ...

最新文章

  1. python过滤器 lambada表达式 可变元组字典参数**kwargs
  2. quartus编译错误不支持芯片_介绍一下如何重新编译Arduino 16U2 的Firmware
  3. 高德地图api接口文档_在 R 语言里面调用高德地图接口:地理编码与路径规划
  4. Maven基础及概念
  5. 计算机学院优秀主讲教师评选细则,关于转发《华南师范大学第二届“我最喜爱的导师”评选活动实施细则》的通知...
  6. fetch移动端浏览器兼容问题
  7. orm2 中文文档 1. 连接到数据库
  8. 第2章[2.2] Ext JS多类型终端-电脑、移动端(手机、平板)
  9. 简单的签到代码_签到功能,用 MySQL 还是 Redis ?
  10. Go Module 工程化实践(二):go get 取包原理篇
  11. MOSS 2007 / WSS 3.0 运行在Windows Server 2008上不能上传大于28M的文件【续】
  12. Flask 的 数据库连接 与 DBUtils 数据库连接池
  13. HouseMD v0.2.1 发布,比Btrace更实用运行时诊断工具
  14. 推荐计算机科学类的经典书籍
  15. excel自定义功能区图标_自定义Excel条件格式图标
  16. iPhone开发逻辑分辨率
  17. web前端代码开发工具_Web开发人员的有用代码比较工具
  18. 新的时间处理工具joda
  19. C语言 switch语句举例说明(类比坐电梯来理解)
  20. 使用cordova将Ext JS 6.2的Modern应用程序打包为安卓APP

热门文章

  1. 模型花费几十万美元,五年之间指导无数项目,才发现负样本用的是null?
  2. 从60多场技术面试中,我总结了这份面试经验
  3. 深度学习框架大战,我该选哪个?
  4. 并发编程基础篇——第二章(如何创建线程)
  5. 分组表管理之保存分组表数据
  6. 深层神经网络与优化算法
  7. 爬虫之使用verify参数忽略CA证书
  8. 通俗易懂的TCP里面的三次握手以及四次挥手
  9. 在报文摘要算法MD5中,首先要进行明文分组与填充,其中分组时明文报文摘要按照(42)位分组。【答案】C
  10. 技术19期:1分钟入门数据治理!必看!【技术篇】