背景

Read the fucking source code! --By 鲁迅

A picture is worth a thousand words. --By 高尔基

说明:

Kernel版本:4.14

ARM64处理器,Contex-A53,双核

使用工具:Source Insight 3.5, Visio

1. 概述

上篇文章分析到malloc/mmap函数中,内核实现只是在进程的地址空间建立好了vma区域,并没有实际的虚拟地址到物理地址的映射操作。这部分就是在Page Fault异常错误处理中实现的。

Linux内核中的Page Fault异常处理很复杂,涉及的细节也很多,malloc/mmap的物理内存映射只是它的一个子集功能,下图大概涵盖了出现Page Fault的情况:

下边就开始来啃啃硬骨头吧。

2. Arm64处理

Page Fault的异常处理,依赖于体系结构,因此有必要来介绍一下Arm64的处理。

代码主要参考:arch/arm64/kernel/entry.S。

Arm64在取指令或者访问数据时,需要把虚拟地址转换成物理地址,这个过程需要进行几种检查,在不满足的情况下都能造成异常:

地址的合法性,比如以39有效位地址为例,内核地址的高25位为全1,用户进程地址的高25位为全0;

地址的权限检查,这里边的权限位都位于页表条目中;

从上图中可以看到,最后都会调到do_mem_abort函数,这个函数比较简单,直接看代码,位于arch/arm64/mm/fault.c:

/*

* Dispatch a data abort to the relevant 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);

struct siginfo info;

if (!inf->fn(addr, esr, regs))

return;

pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n",

inf->name, esr, addr);

mem_abort_decode(esr);

info.si_signo = inf->sig;

info.si_errno = 0;

info.si_code = inf->code;

info.si_addr = (void __user *)addr;

arm64_notify_die("", regs, &info, esr);

}

该函数中关键的处理:根据传进来的esr获取fault_info信息,从而去调用函数。struct fault_info用于错误状态下对应的处理方法,而内核中也定义了全局结构fault_info,存放了所有的情况。

主要的错误状态和处理函数对应如下:

static const struct fault_info fault_info[] = {

{ do_bad,SIGBUS, 0,"ttbr address size fault"},

{ do_bad,SIGBUS, 0,"level 1 address size fault"},

{ do_bad,SIGBUS, 0,"level 2 address size fault"},

{ do_bad,SIGBUS, 0,"level 3 address size fault"},

{ do_translation_fault,SIGSEGV, SEGV_MAPERR,"level 0 translation fault"},

{ do_translation_fault,SIGSEGV, SEGV_MAPERR,"level 1 translation fault"},

{ do_translation_fault,SIGSEGV, SEGV_MAPERR,"level 2 translation fault"},

{ do_translation_fault,SIGSEGV, SEGV_MAPERR,"level 3 translation fault"},

{ do_bad,SIGBUS, 0,"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,SIGBUS, 0,"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"},

...

};

从代码中可以看出:

出现0/1/2/3级页表转换错误时,会调用do_translation_fault,实际中do_translation_fault最终也会调用到do_page_fault;

出现1/2/3级页表访问权限的时候,会调用do_page_fault;

其他的错误则调用do_bad,其中未列出来的部分还包括do_sea等操作函数;

do_translation_fault

do_page_fault

do_page_fault函数为页错误异常处理的核心函数,与体系结构相关,上图中的handle_mm_fault函数为通用函数,也就是不管哪种处理器结构,最终都会调用到该函数。

3. handle_mm_fault

handle_mm_fault用于处理用户空间的页错误异常:

进程在用户模式下访问用户虚拟地址,触发页错误异常;

进程在内核模式下访问用户虚拟地址,触发页错误异常;

从do_page_fault函数的流程图中也能看出来,当触发异常的虚拟地址属于某个vma,并且拥有触发页错误异常的权限时,会调用到handle_mm_fault函数,而handle_mm_fault函数的主要逻辑是通过__handle_mm_fault来实现的。

流程如下图:

3.1 do_fault

do_fault函数用于处理文件页异常,包括以下三种情况:

读文件页错误;

写私有文件页错误;

写共享文件页错误;

3.2 do_anonymous_page

匿名页的缺页异常处理调用本函数,在以下情况下会触发:

malloc/mmap分配了进程地址空间区域,但是没有进行映射处理,在首次访问时触发;

用户栈不够的情况下,进行栈区的扩大处理;

3.3 do_swap_page

如果访问Swap页面出错(页面不在内存中),则从Swap cache或Swap文件中读取该页面。

由于在4.14内核版本中,do_swap_page调用的很多函数都是空函数,无法进一步的了解,大体的流程如下图:

3.4 do_wp_page

do_wp_page函数用于处理写时复制(copy on write),会在以下两种情况处理:

创建子进程时,父子进程会以只读方式共享私有的匿名页和文件页,当试图写的时候,触发页错误异常,从而复制物理页,并创建映射;

进程创建私有文件映射,读访问后触发异常,将文件页读入到page cache中,并以只读模式创建映射,之后发生写访问后,触发COW;

关键的复制工作是由wp_page_copy完成的:

【原创】(十)Linux内存管理 - zoned page frame allocator - 5

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

【原创】(六)Linux内存管理 - zoned page frame allocator - 1

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

Linux内存管理 (11)page引用计数

专题:Linux内存管理专题 关键词:struct page._count._mapcount.PG_locked/PG_referenced/PG_active/PG_dirty等. Linux的内 ...

【原创】(七)Linux内存管理 - zoned page frame allocator - 2

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

【原创】(九)Linux内存管理 - zoned page frame allocator - 4

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

【原创】(八)Linux内存管理 - zoned page frame allocator - 3

背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

Linux内存描述之内存页面page–Linux内存管理(四)

服务器体系与共享存储器架构 日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDriver ...

伙伴系统之避免碎片--Linux内存管理(十六)

1 前景提要 1.1 碎片化问题 分页与分段 页是信息的物理单位, 分页是为了实现非连续分配, 以便解决内存碎片问题, 或者说分页是由于系统管理的需要. 段是信息的逻辑单位,它含有一组意义相对完整的信 ...

伙伴系统之伙伴系统概述--Linux内存管理(十五)

在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法. Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, ...

随机推荐

采用MVC模式JDBC演示案例

MVC三层架构: Model 模型层,数据处理和业务逻辑 View 视图层,为客户展示内容 Control 控制层,协调控制,更新模型 案例如下: 1.获得数据库连接 package com.db; ...

【hihoCoder】1121:二分图一·二分图判定

题目   http://hihocoder.com/problemset/problem/1121 无向图上有N个点,两两之间可以有连线,共有M条连线. 如果对所有点进行涂色(白/黑),判定是否存 ...

javascript_basic_03之函数、循环、数组

1.函数:函数(Function),方法(Method),过程(Procedure): 2.默认为假的情况: ①if(0){}:②if(0.0){}:③if(null){}:④if("&qu ...

centos 软件安装 删除

centos的软件安装大致可以分为两种类型: [centos]rpm文件安装,使用rpm指令  类似[ubuntu]deb文件安装,使用dpkg指令 [centos]yum安装   类似[ubuntu ...

Android实现计时与倒计时(限时抢购)的几种方法

在购物网站的促销活动中一般都有倒计时限制购物时间或者折扣的时间,这些都是如何实现的呢? 在一个安卓客户端项目中恰好遇到了类似的问题,一开始使用的是Timer与 TimerTask, 虽然此方法通用,但 ...

仿360新闻的热搜图片,win8风格随机九宫格布局

360新闻地址:http://sh.qihoo.com/i/ 感觉这效果挺好的,随机九宫格,在不少地方可以用到,就研究了下他的源码,基本原理就是预先定义好几种布局模块,然后根据需要进行拼接,具体代码可 ...

Netty实战一之异步和事件驱动

Netty是一款异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端. 使用Netty你可以并不是很需要网络编程.多线程处理.并发等专业Java知识的积蓄. Net ...

PHP加密与编码技术

md5加密: string  md5( string $str [,bool $raw output=false]) md5加密方法用的挺多,有两个参数,第一个参数是要加密的字符串,第二个参数默认为f ...

ttl传输中过期

上renren时遇到一问题,突然间就无法登陆,看了下网络,正常呀,别的网站完全ok,就这不成,所以就ping了一下做以校验:如下图示:传输中过期ttl,这问题少见,新鲜呀:赶紧查了查:原来可能是产生了 ...

WPF 每次只打开一个窗口

if(downListControl == null || downListControl.IsVisible == false) { downListControl = new DownloadLi ...

Linux内存page,【原创】(十四)Linux内存管理之page fault处理相关推荐

  1. Linux日志写空,(十四)Linux日志管理

    第一节 日志管理简介 1.日志服务 在CentOS6.x中日志服务已经由rsyslogd取代了原先的syslogd服务.rsyslogd日志服务更加先进,功能更多 但是不论该服务的使用,还是日志文件的 ...

  2. Linux的基本学习(十四)——进程管理(下)与SELinux

    Linux的基本学习(十四)--进程管理(下)与SELinux 前言 进程这部分内容真是不少,来,我们继续跟着鸟哥学习. 特殊文件与进程 具有SUID/SGID权限的命令执行状态 SUID的权限其实与 ...

  3. Cty的Linux学习笔记(十四)

    Linux学习笔记--第十四篇 环境变量配置文件: /etc/profile:预设了几个重要的变量,例如PATH,USER,LOGNAME,MAIL,INPUTRC,HOSTNAME,HISTSIZE ...

  4. Linux(b站视频兄弟连)自学笔记第十四章——日志管理

    Linux(b站视频兄弟连)自学笔记第十四章--日志管理 简介 rsyslogd 日志轮替 简介 rsyslogd 日志轮替

  5. 系统集成项目管理工程师(软考中级)—— 第二十四章 收尾管理、知识产权、法规标准规范 笔记分享

    前言 现在分享一些笔记给大家,希望能够帮助大家并顺利通过软考. 幕布地址:第二十四章 收尾管理.知识产权.法规标准规范 - 幕布 概述 大数据 收尾 收尾管理工作 ①项目验收工作 是项目收尾管理中的首 ...

  6. linux内存管理(十四)-内存OOM触发分析

    在内存分配路径上,当内存不足的时候会触发kswapd.或者内存规整,极端情况会触发OOM,来获取更多内存. 在内存回收失败之后,会进行OOM,OOM的入口是__alloc_pages_may_oom, ...

  7. 嵌入式Linux驱动笔记(二十四)------framebuffer之使用spi-tft屏幕(上)

    你好!这里是风筝的博客, 欢迎和我一起交流. 最近入手了一块spi接口的tft彩屏,想着在我的h3板子上使用framebuffer驱动起来. 我们知道: Linux抽象出FrameBuffer这个设备 ...

  8. 【正点原子Linux连载】第十四章 Qt控制LED 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  9. 【Linux命令】《鸟哥Linux基础》第十六章 进程管理与SELinux初探

    第十六章 进程管理与SELinux初探 16.1 什么是进程(process) Linux下的所有命令与你能够执行的操作 ===>都与权限有关 如何判断权限? 账号管理中的UID.GID:文件属 ...

  10. 实验linux下的编程,实验四 Linux下的C语言编程;

    <实验四 Linux下的C语言编程;>由会员分享,可在线阅读,更多相关<实验四 Linux下的C语言编程;(5页珍藏版)>请在人人文库网上搜索. 1.实验四Linux 下的 C ...

最新文章

  1. HDU - 6333 Problem B. Harvest of Apples(莫队变形+思维+组合数学,好题)
  2. 自己写了一个多行文本溢出文字补全的小库, 说不定你会用得到的
  3. php ldap支付,php – 实现LDAP合规性
  4. ubuntu 16.04安装VMwareTools
  5. linux 路由器_为什么我要建立自己的自制Linux路由器
  6. 无法启用Windows Hello-某些设置由您的组织管理
  7. [Ext JS ] 7.25.1 Form或者面板自动定位到错误的输入框
  8. C#中DllImport用法
  9. JavaEE学习14--过滤器filter
  10. 超融合架构与传统IT架构的区别
  11. 一款可以通过经度纬度精确查询天气的工具
  12. 一文看懂AutoML
  13. Android 清理应用缓存
  14. linux当前文件下的文件数,Linux下统计当前文件夹下的文件个数、目录个数(转)...
  15. libero soc 仿真74HC161
  16. Postgresql多行合并一行
  17. 【SRAM】CubeMX配置STM32H743+IS61WV204816外部扩展SRAM
  18. 安卓4.4.4安装哪个微信版本_安卓用户喜大普奔!安卓版微信7.0.13内测版发布,支持深色模式!...
  19. 新一代的无线通信技术(转)
  20. vs2022安装详细

热门文章

  1. iOS之深入解析dyld与ObjC关联的底层原理
  2. 没想到MySQL还会问这些...
  3. 征战蓝桥 —— 2014年第五届 —— C/C++A组第4题——史丰收速算
  4. 母版页 中 html 乱码,Thymeleaf使用技巧:使用片段(fragment)实现母版页(Layout)功能...
  5. 如何使用jquery_好程序员web前端学习路线分享jQuery学习技巧
  6. DM8 jdbc调用存储过程传参list<实体类>
  7. 圈钱跑路 发行自己的ERC20 Token
  8. 关于逆元的概念、用途和可行性的思考(附51nod 1013 和 51nod 1256)
  9. 每天一道LeetCode-----计算最长的元素连续序列长度
  10. 每天一道LeetCode-----计算二叉树的最大深度及最小深度,判断二叉树是否是高度平衡二叉树