ARMV7架构用户虚拟地址转PFN代码异常及常驻内存虚拟地址咨询
问题解答
1. pte返回空是否表示虚拟地址已被换出?
前置说明
ARMV7架构实际仅使用2级页表机制,Linux内核为了兼容多架构页表设计,对PGD/PUD/PMD做了层级折叠处理,你观测到pgd_val(*pgd)、pud_val(*pud)、pmd_val(*pmd)取值一致属于正常现象,不是运行错误。
结论
该现象不代表虚拟地址被换出,核心原因如下:
- 页面被换出时,页表项不会被清空为0,内核会在页表项中存储swap分区偏移、swap文件位置等换出标记信息,不会触发
pte为空的判断 - 你观测到
pte_offset_kernel()返回空,通常是以下几类原因:- 传入的用户虚拟地址没有对应有效VMA(虚拟内存区域),本身属于非法地址
- 虚拟地址对应的VMA存在,但还未触发缺页异常分配物理页,属于已预留未分配的地址范围
- 遍历页表时没有持有
current->mm->mmap_lock(旧版内核为mmap_sem)锁,遍历过程中页表刚好被回收、调整,导致偶发空指针问题 - 接口使用错误:
pte_offset_kernel()是专为内核地址空间页表遍历设计的接口,遍历用户态地址应使用pte_offset_map(),否则容易出现兼容性问题
2. 常驻内存不被换出的用户虚拟地址类型
满足以下任意条件的用户虚拟地址不会被系统换出:
- 调用
mlock()/mlock2()/mlockall()系统调用显式锁定的地址范围:锁定后页面不会被回收、换出,直到进程主动解锁或者进程退出。普通进程可锁定的内存大小受RLIMIT_MEMLOCK资源限制,超出限制的锁定操作需要进程持有CAP_IPC_LOCK权限 - 调用
mmap()映射内存时携带MAP_LOCKED标记的地址区域:映射完成后自动锁定,效果和mlock()完全一致 - 特殊设备映射的内存区域:比如通过
/dev/mem、/dev/vfio等字符设备映射的IO物理地址、设备内存,这类内存本身不参与系统页回收逻辑 - 携带
SHM_LOCK标记的System V共享内存、POSIX共享内存:所有挂载该共享内存的进程对应的虚拟地址都不会被换出
内容的提问来源于stack exchange,提问作者md.jamal
相关产品推荐
相关产品推荐

