【Linux 内核 内存管理】mmap 系统调用源码分析 ③ ( vm_mmap_pgoff 函数执行流程 | vm_mmap_pgoff 函数源码 )
文章目录
- 一、vm_mmap_pgoff 函数执行流程
- 二、vm_mmap_pgoff 函数源码
调用 mmap
系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 " 整数倍 " , 如果偏移是内存页大小的整数倍 , 则调用 sys_mmap_pgoff
函数 , 继续向下执行 ;
在 sys_mmap_pgoff
系统调用函数 中 , 最后调用了 vm_mmap_pgoff
函数 , 继续向下执行 ;
一、vm_mmap_pgoff 函数执行流程
在 vm_mmap_pgoff
函数中 ,
首先 , 以 " 写者 " 身份 , 向 Linux 内核申请 读写 " 信号量 " 权限 ;
然后 , 如果 读写 " 信号量 " 权限 申请通过 , 那么调用 do_mmap_pgoff
函数 , 执行 创建 " 内存映射 " 的过程 , 特别注意 , 这是 创建 " 内存映射 " 的 核心函数 , 下一篇博客着重讲该函数 ;
再后 , 创建 " 内存映射 " 完成后 , 释放 " 读写信号量 " ;
最后 , 处理 " 内存页 " 锁定问题 , 如果需要将 内存映射 的 内存页 锁定在 虚拟内存 中 , 直接进行处理即可 , 在 物理地址空间 分配 内存页 , 并将 虚拟地址空间 的 内存页 映射到 物理内存页 中 ;
二、vm_mmap_pgoff 函数源码
vm_mmap_pgoff
函数定义在 Linux 内核源码中的 linux-4.12\mm\util.c#296 位置 ;
vm_mmap_pgoff
函数源码如下 :
unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long pgoff)
{
unsigned long ret;
struct mm_struct *mm = current->mm;
unsigned long populate;
LIST_HEAD(uf);
ret = security_mmap_file(file, prot, flag);
if (!ret) {
if (down_write_killable(&mm->mmap_sem))
return -EINTR;
ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff,
&populate, &uf);
up_write(&mm->mmap_sem);
userfaultfd_unmap_complete(mm, &uf);
if (populate)
mm_populate(ret, populate);
}
return ret;
}
源码路径 : linux-4.12\mm\util.c#296
偶是老李头: while (p_start < p_end) 走不进去呢?
小码农叔叔: 优质好文,博主文章干货很多,技术细节把控非常好,实用性不错,对日常工作很有帮助,感谢博主的分享,期待博主持续更新!同时也期待博主的指点哦
陈橘又青: 这篇博客让我对某个领域产生了浓厚的兴趣,强烈推荐给大家。并且让我想起了我这篇文章也有异曲同工之妙,欢迎前来指点我一番!我必然用心回报!
wqh331441: 去搜索镜像版,还有的
韩楚风: 优质好文,博主的文章细节很到位,兼顾实用性和可操作性,感谢博主的分享,期待博主持续带来更多好文