在进入正题之前先看看vmalloc是怎么申请内存的(虽然在前面的文章中已经说过了)。管理vmalloc分配空间用到的数据结构是vm_struct。首先用slab分配一个vm_struct实例,然后从vm_struct链表中找到一个合适的位置准备插入这个实例。这个实例只是用来管理这块内存的,那下面就开始申请这些内存,也就是一页一页地从buddy system中分配单页来填充一个page数组(这就是vmalloc分配得到的内存)。那怎么访问这些分配的内存呢?下面就逐层地建立pgd、pmd、pte结构中的值。释放vmalloc申请的空间的过程就是逆过来的。

下面进入正题!

在逐层建立pgd、pmd、pte的时候并不触及当前进程的页表,因此当内核态的进程在访问非连续内存区时就会发生缺页(进程页表中的表项为空)。处理程序先检查这个缺页线性地址是否在主内核页表中(init_mm.pgd),如果发现就把对应的值拷贝到进程的页表项中,然后恢复进程的执行。

static int vmalloc_fault(unsigned long address){        unsigned long pgd_paddr;        pmd_t *pmd_k;        pte_t *pte_k;        pgd_paddr = read_cr3();        pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);if (!pmd_k)return -1;        pte_k = pte_offset_kernel(pmd_k, address);if (!pte_present(*pte_k))return -1;return 0;}

通过read_cr3函数可以获得当前进程页全局目录的物理地址。然后调用vmalloc_sync_one获得pmd_k,下面看一下这个函数的实现:

static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address){        unsigned index = pgd_index(address);        pgd_t *pgd_k;        pud_t *pud, *pud_k;        pmd_t *pmd, *pmd_k;        pgd += index;        pgd_k = init_mm.pgd + index;if (!pgd_present(*pgd_k))return NULL;        pud = pud_offset(pgd, address);        pud_k = pud_offset(pgd_k, address);if (!pud_present(*pud_k))return NULL;        pmd = pmd_offset(pud, address);        pmd_k = pmd_offset(pud_k, address);if (!pmd_present(*pmd_k))return NULL;if (!pmd_present(*pmd)) {                set_pmd(pmd, *pmd_k);                arch_flush_lazy_mmu_mode();        } else                BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));return pmd_k;}

从init_mm.pgd中取得对应的项,这样开始逐层检查address对应的项是否存在。直到检查到pmd的时候如果还存在的话就设置pmd然后返回。刚开始看的时候这里有点不明白:为什么只是设置pmd?pgd、pud就不管了吗?如果仔细想一想内核中多层页表的结构就清楚了,设置这些只是一些冗余的操作。但是再返回来想一下,如果设置了pgd的话还需要设置pmd吗?因为设置了pgd后找到的pmd也不是过去所能找到的那个pmd了。感慨一下自己的逻辑思维的漏洞百出。看完缺页处理之后对vmalloc分配内存的利用也有了进一步地理解。:)

然后检查一下pte,返回对应的结果。

------------------------------------

个人理解,欢迎拍砖。

转载于:https://www.cnblogs.com/ggzwtj/archive/2011/08/19/2145067.html

非连续内存区缺页异常处理相关推荐

  1. 操作系统-- 连续内存分配、非连续内存分配

    文章目录 一.连续内存分配 1.内存碎片的问题 (1)外部碎片 (2)内部碎片 2.连续内存分配算法 (1)首次适配 (2)最优适配 (3)最差适配 3.碎片整理方法 4.连续内存分配的缺点 二.非连 ...

  2. 清华大学《操作系统》(六):非连续内存分配 段式、页式、段页式存储管理

    背景 连续内存分配给内存分配带来了很多不便,可能所有空闲片区大小都无法满足需求大小,这个分配就会失败.基于这种现状,就有了非连续内存分配的需求.非连续分配成功的几率更高,但也面对更多的问题,比如分配时 ...

  3. 操作系统 非连续分配_操作系统中的连续和非连续内存分配

    操作系统 非连续分配 In this article, we will learn about the different types of memory management techniques ...

  4. 【操作系统/OS笔记05】非连续内存分配:分段、分页、页表

    本次笔记内容: 4.1 非连续内存分配:分段 4.2 非连续内存分配:分页 4.3 非连续内存分配:页表 文章目录 为什么需要非连续内存分配 非连续分配的优劣 分段(segment) 分段寻址方案 分 ...

  5. OS学习笔记-6(清华大学慕课) 非连续内存分配管理

    非连续内存分配的需求 有可能找不到连续的一块内存空间满足进程需求 连续分配存在内碎片,外碎片,内存利用率比较低 非连续内存分配目标:提高内存利用效率以及管理灵活性 于是由于非连续内存块的大小分成了:段 ...

  6. 连续内存分配与非连续内存分配

    连续内存分配 首次适配:空闲分区以地址递增的次序链接.分配内存时顺序查找,找到大小能满足要求的第一个空闲分区. 最优适配:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区. 最坏适配:空闲 ...

  7. 操作系统五: 非连续内存分配

    如何建立虚拟地址和物理地址之间的转换? 分段(Segmentation) 程序的分段地址空间     分段寻址方案 分页(Paging) 逻辑地址空间被划分为页 页表(Page Table)

  8. 缺页异常处理-do_page_fault

    //regs 发生异常时寄存器的值 //error_code 5位的值,第3位标志异常发生在内核态还是用户态 do_page_fault函数: { //获得产生缺页异常的地址,该地址保存在cr2寄存器 ...

  9. 连续内存分区式内存管理

    目录 前言 分区式内存管理 动态分区内存管理 总结 本笔记参考黄工的https://mp.weixin.qq.com/s/k0W_LqI1zBAYC1GU1U2HQA 前言 内存管理模块主要负责内存的 ...

  10. 操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法

    操作系统4小时速成:内存管理,程序执行过程,扩充内存,连续分配,非连续分配,虚拟内存,页面替换算法 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测 ...

最新文章

  1. three.js 贴图只显示颜色_C4D作品“花里胡哨”?我怀疑你贴图方式有问题……
  2. ubuntu系统声音_今日热闻 | 小米11有望首发骁龙875、折叠iPhone测试、新规禁止网购忽悠打折、印度真米粉、M1 Mac运行Ubuntu...
  3. 关于软件外包的一些看法(转)
  4. 一道面试题,想明白之后好像锤自己几下~~
  5. 数据治理的理论实践与发展趋势
  6. svn教程----TortoiseSVN常用操作
  7. 小s结尾与大S结尾的汇编语言差异
  8. Angular structural指令host element的定位调试
  9. CGCKD2021大会报告整理(4)--风格迁移
  10. python writelines_Python文件writelines()方法
  11. webservice接口和restful接口哪个更好?
  12. php模块出现警告,PHP警告:模块已在第0行的Unknown中加载
  13. 【QT】QT从零入门教程(五):图像文件操作 [新建打开保存]
  14. 华为京东联手,火拼小米生态链!
  15. 20210621:力扣第246周周赛(上)
  16. lsb_slam Tracking线程 SE3Tracking 欧式变换矩阵跟踪参考帧 加权高斯牛顿优化算法WLM 最小二乘优化 归一化方差的光度误差函数 偏导数雅克比矩阵J 线性方程组LDLT求解
  17. BugkuCTF_Web——“秋名山老司机”、“速度要快”、“cookies欺骗”
  18. java poi 导出excel不能超过65536行
  19. python爬虫实例手机_10个python爬虫入门实例
  20. 联想服务器怎么做系统备份,联想笔记本怎么做系统备份

热门文章

  1. 诗一首,程序员不仅仅只会写程序
  2. SAP Client Copy
  3. [备忘]java读取与写入文件的五种方式
  4. 推荐一个准确率99.9%的离线IP地址定位服务!
  5. 收藏啦~ Github上 10 个开源免费且优秀的后台控制面板
  6. 不用找了,基于 Redis 的分布式锁实战来了
  7. 阿里巴巴16字真言 | 管理者的基本要求是什么?
  8. 一位程序员的十年工作总结,值得每位互联网人看
  9. 坑系列 --- 重构过程中的过度设计
  10. python 如何封装dll_python怎么封装dll