- 内存管理之预备知识
1.1 请简述内存架构中UMA和NUMA的区别
1.2 CPU访问各级存储结构的速度是否一样?
1.3 请绘制内存管理常用的数据结构的关系图,如mm_struct、VMA、vaddr、page、PFN、PTE、zone、paddr和pg_data等,并思考如下转换关系
1.3.1 如何由mm_struct和vaddr找到对应的vma?
1.3.2 如何由page和VMA找到vaddr?
1.3.3 如何由page找到所有映射的VMA?
1.3.4 如何由VMA和vaddr找出相应的page数据结构?
1.3.5 page和PFN之间如何互换?
1.3.6 PFN和paddr之间如何互换?
1.3.7 page和PTE之间如何互换?
1.3.8 zone和page之间如何互换?
1.3.9 zone和pg_data之间如何互换?
1.4 在risc-v内核中,内核映像文件映射到内核空间的什么地方?
1.5 在risc-v内核中,用户空间和内核空间如何划分的?
1.6 在系统启动时,riscv linux内核如何知道系统有多大物理内存?
1.7 物理内存如何添加到伙伴系统中,是一页一页添加,还是以 来添加的? - 物理内存与虚拟内存
2.1 请简述linux内核在理想情况下页面分配器(page allocator)是如何分区出连续物理页面的
2.2 在页面分配器中,如何从分配掩码(gfp_mask)中确定可以从哪些zone中分配内存?
2.3 页面分配器是按照什么方向来扫描zone的?
2.4 为用户进程分配物理内存时,分配掩码应该选用GFP_KERNEL,还是GFP_HIGHUSER_MOVABLE?
2.5 在中断上下文中能不能调用包含GFP_KERNEL分配掩码的内存分配函数?
2.5.1 zone水位
2.5.2 GFP_ATOMIC
2.5.3 在使用GPF_KERNEL情况下,什么时候才睡眠?
2.6 如何判断一个zone是否满足分配需求?
2.6.1 lowmem_radio概念
参考
2.7 在释放页面时,页面分配器是如何进行空闲页面合并的?
2.7.1 page head概念
2.7.2 迁移类型的选择以及使用
2.7.2.1 迁移类型的定义:
2.7.2.2 迁移类型的计算以及设置:
2.7.2.3 迁移类型的使用
2.8 在早期的linux内核中,以字节为大小的内存块分配机制有什么缺点?slab机制如何克服这些缺点?
2.9 slab分配器如何分配和释放小内存块的?
2.10 slab分配器中有一个高速缓存着色(cache color)的概念,着色有什么作用?
2.11 slab分配器增长并导致大量不用的空闲对象产生,该如何解决?
2.12 什么是对象缓存池?
2.13 在创建一个slab对象描述符时,如何确定一个slab占用多少个物理页面、有多少个对象、着色区有多少个?
2.14 slab分配器的布局有三种模式-正常模式、OBJFREELIST_SLAB模式、OFF_SLAB模式,他们有什么区别?
2.15 什么时候给slab分配器分配物理内存?
2.16 slab分配器中有一个slab管理区freelist,那么这个slab管理区域是如何管理空闲对象的呢?
2.17 slab分配器如何保证在多CPU的大型计算机中的并发访问性能?
2.18 kmalloc、vmalloc和malloc函数之间的区别以及实现上的差异?
2.19 linux内核是如何管理进程的用户态地址空间的?
2.20 进程地址空间的属性如何转换成硬件能识别的属性?
2.21 进程地址空间是离散的,那linux内核如何保证这些地址空间不会冲突?
2.22 linux内核如何实现进程地址空间的快速查询和插入?
2.22.1 查找
2.22.2 插入
2.23 find_vma()函数查找符合哪些条件的vma?
2.24 malloc()函数返回的内存是否马上就被分配物理内存?
2.25 假设不考虑libc的因数,malloc()分配100字节,那么实际上内核为其分配100字节吗?
2.26 假设使用printf()输出的指针bufA和bufB指向的地址是一样的,那么在内存中这两个虚拟内存块是否冲突呢?
2.26.1 sbrk和brk使用
2.26.1 brk流程图
2.27 vm_normal_page()函数返回什么页面的page数据结构?为什么内存管理代码中需要这个函数?
2.27.1 页面分类
2.27.2 riscv中的special位
2.27.3 vm_normal_page函数实现
2.28 请简述get_user_pages()函数的作用和实现流程。
2.28.1 get_user_pages()函数的作用
2.28.2 get_user_pages()使用
2.28.3 流程图
2.28.3 __get_user_pages()函数实现
2.29 请简述follow_page()函数的作用和实现流程。
2.29.1 follow_page()函数的作用
2.29.2 follow_page使用
2.29.2 follow_page()函数的实现流程
2.30 SYSCALL_DEFINE(brk, unsigned long)这个宏是如何展开的?
2.31 在riscv内核中,用户空间如何划分呢?brk区域的起始地址和结束地址在哪里?
2.32 请简述私有映射和共享映射的区别
2.32.1 mmap介绍
2.32.2 映射的类型
2.32.3 mmap流程图
2.33 在以下代码中,为什么第二次调用mmap时,linux内核没有捕捉到地址重叠并返回失败?
2.34 请简述RISC-V处理器在缺页异常发生之后是如何找到发生异常的类型和错误地址的。
2.34.1 分析handle_exception
2.34.2 task_struct、thread_info、stack、pt_regs的关系
2.34.3 riscv异常处理流程图
2.34.4 回答题目的问题
2.35 当RISC-V处理器发生了缺页异常时,如何知道它是因为读内存还是写内存发生的缺页异常?
2.35.1 load access fault和load page fault区别
2.35.2 读内存异常和写内存异常
2.36 当处理器发生了缺页异常时,如何判断发生异常的地址是可以修复还是不能修复的?
2.37 在do_page_fault()函数处理过程中需要考虑哪些情况?
2.37.1 fault_flag类型说明
2.37.2 do_page_fault()源码分析
2.37.3 do_page_fault流程图
2.38 主缺页(major fault)和次缺页(minor fault)有什么区别?
2.39 对匿名页面的缺页异常,判断条件是什么?
2.40 对文件映射页面的缺页异常,判断条件是什么?
2.41 什么是写时复制类型的缺页异常?判断条件是什么?
2.41.1 写时复制定义
2.41.2 写时复制的判断条件
2.42 在写时复制处理中,有两种方式,一种是复用发生异常的页面,另外一种是写时复制,那究竟什么类型的页面可以复用?什么类型的页面必须写时复制呢?
2.43 什么情况下可以安全地调用pte_offset_map()函数?什么情况下不行?
2.44 在切换新的页表之前要对页表内容清零并刷TLB,这是为什么?
2.46 在一个多核的smp系统中,是否多个CPU内核可以同时对同一个页面发生缺页异常?若可以,请描述一个发生的场景,并描述如何保证这几个缺页异常的内核路径对同一个页面的操作不会导致竞争问题。 - 内存管理之高级主题
3.1 page数据结构中的_refcount和_mapcount有什么区别?
3.1.1 _refcount
3.1.2 _refcount的使用场景
3.1.2 _mapcount
3.2 匿名页面和高速缓存页面有什么区别?
3.3 page数据结构中有一个锁,称为页锁,请问trylock_page()和lock_page()有什么区别?
3.4 请画出page数据结构中flags成员的布局示意图
3.5 请列举page数据结构中_refcount和_map_count计数的使用案例
3.6 请简述page数据结构中mmaping成员的作用
3.7 在linux2.4.x内核中,如何从一个页面中找到映射该页面的VMA?RMAP可以带来哪些便利?
3.8 阅读linux5.15内核RMAP机制的代码,画出父子进程之间VMA、AVC、AV以及page等数据结构之间的关系图
3.9 在linux2.6.34内核中,RMAP机制采用了新的实现,Linux 2.6.33内核和之前的版本中的RMAP机制称为旧版本RMAP,那么旧版本RMAP机制中,如果父进程有1000个子进程,每个子进程都有一个VMA,每个VMA里面有1000个匿名页面,当所有子进程的VMA同时发生写时复制时会是什么情况呢?
3.10 kswapd内核线程何时会被唤醒?
3.11 LRU链表如何知道页面的活动频繁程度?
3.11.1 mark_page_accessed()函数
3.11.2 page_check_references()函数
3.11.3 page_referenced()函数
3.11.4. 什么时候会去设置PG_active和PG_referenced这两个标志位?
3.11.5 . 什么时候使用PG_active和PG_referenced这两个标志位?
3.11.6 _PAGE_ACCESSED(PTE_AF)和PG_active、PG_referenced的关系
3.12 kswapd按照什么原则来换出页面?
3.13 kswapd按照什么方向来扫描zone?
3.14 kwapd以什么标准来退出扫描LRU链表?
3.15 移动设备操作系统(如安卓),没有交换分区或者交换文件,kswapd会扫描匿名页面LRU吗?
3.16 swappiness的含义是什么?kswapd如何计算匿名页面和页面高速缓存之间的扫描比重?
3.17 当系统中充斥着大量只访问一次的文件访问时,kswapd如何来规避这种访问?
3.18 在回收页面高速缓存时,对脏的页面高速缓存,kswapd会马上回写吗?
3.18.1 shrink_page_list 内存回收的核心函数
3.19 内核中有哪些页面会被kswapd回写到交换分区?
3.20 请简述匿名页面的生命周期
3.20.1. 匿名页面诞生
3.20.2. 匿名页面的使用
3.20.3. 匿名页面的换出
3.20.4. 匿名页面的换入
3.20.5. 匿名页面的释放
3.20.6 总结
3.21 在什么情况下会产生匿名页面
3.22 在什么条件下会是释放匿名页面
3.23 页面迁移是基于什么原理来实现的
3.24 内核中有哪些页面可以迁移?
3.25 内核本身使用的页面是否可以迁移?为什么?
3.26 在页面迁移的过程中需要注意些什么?
3.27 什么是传统LRU页面和非LRU页面?
3.28 内存规整是基于什么原理来实现的?
3.29 如何触发内存规整?
3.30 哪些页面适合做内存规整?哪些页面不适合做内存规整?
3.31 KSM是基于什么原理来合并页面的?
3.32 内容相同的页面在KSM里是如何被扫描和合并的?其工作流程是什么样的?
3.33 若稳定的节点的hlist中堆积了几百万个rmap_item,那么对系统会产生什么影响?
3.34 新版本的KSM对稳定的节点做了哪些优化?
3.35 在KSM机制里,合并过程中把页面设置成了保护的函数write_protect_page()中有如下判断。这个判断的依据是什么?
3.36 如果多个VMA的虚拟页面同时映射了同一个匿名页面,那么此时page->index应该等于多少?
3.37 匿名页面和KSM页面的区别是什么?
3.37.1 ksm的实现流程图
3.38 页面分配器如何管理空闲页面和分配请求之间的关系?
3.39 什么是页面分配器的快速路径?什么是慢速路径?
3.40 当一个普通的进程恶意占用内存时,页面分配器是如何处理的?
3.41 当一个普通进程处于内存承压的情况下,页面分配器尝试哪些努力来保证分配成功?
3.42 什么情况下页面分配器可以访问系统预留内存?
3.43 在页面分配器中,分配掩码ALLOC_HIGH、ALLOC_HARDER、ALLOC_OOM以及ALLOC_NO_WATERMARKS之间有什么区别?它们各自能访问系统预留内存的百分比是多少?思考为什么页面分配器需要做这样的安排。
3.44 伙伴系统算法是如何减少内存碎片的?
3.45 为什么要把内存分成不同的迁移类型? 这些迁移类型有什么区别?
3.46 假设请求分配order为4的一个内存块,迁移类型是不可迁移(MIGRATE_UNMOVEABLE),但是order大于或等于4的不可迁移类型的空闲链表中没有空闲页块,那么页面分配器会怎么办?
3.47 什么是内存外碎片化?linux内核页面分配器是如何发现外碎片的?
3.48 当发现了内存外碎片,linux-5.15内核是如何处理的? - 内存优化
0. linux-riscv内存管理120问大纲
于 2023-09-13 10:22:15 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)