mmap实现分析
分类:美高梅游戏官网网站

mmap完毕解析

mmap达成深入分析

正文不是介绍mmap函数的施用办法,而是解析其底工完成,相关应用方法兰西网球国际比赛上后生可畏度有那一个材料。Mmap的庐山真面目目实际上便是:为当前经过分配(或找到卡塔尔一个方便的vma,然后为该vma设置相应的缺页管理函数。

大家领略mmap依照flag能够分成无名映射和非无名氏映射,又可分为shared映射和private映射。这样从八个维度,大家就得到了各种璀璨。

(1)无名氏shared映射:fd为-1,可用来老爹和儿子进程通讯。

(2)无名氏private映射:比如malloc大块的内部存款和储蓄器(大于128k卡塔尔。

(3)非无名氏shared映射:管见所及的用于进度通讯格局。

(4)非无名private映射:举个例子程序在运转时加载so时,就是用的这种措施,也就是“写时拷贝”。

下边大家就看下内核中三种格局的区分。

根本中mmap首要有函数sys_mmap_pgoff函数负担落到实处,该函数定义在mm/mmap.c中。

  1. SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
  2. unsigned long, prot, unsigned long, flags,
  3. unsigned long, fd, unsigned long, pgoff)
  4. {
  5. struct file *file = NULL;
  6. unsigned long retval = -EBADF;
  7. if (!(flags & MAP_ANONYMOUS)) { /*无名映射*/
  8. audit_mmap_fd(fd, flags);
  9. if (unlikely(flags & MAP_HUGETLB))
  10. return -EINVAL;
  11. file = fget(fd); /*由fd找到呼应的file结构*/
  12. if (!file)
  13. goto out;
  14. 美高梅游戏官网网站 ,if (is_file_hugepages(file))
  15. len = ALIGN(len, huge_page_size(hstate_file(file)));
  16. } else if (flags & MAP_HUGETLB) {
  17. /*......*/
  18. }
  19. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  20. retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  21. if (file)
  22. fput(file);
  23. out:
  24. return retval;
  25. }

该函数主要功用由vm_mmap_pgoff来实现,而vm_mmap_pgoff重要逻辑正是调用了do_mmap_pgoff。上面咱们看vm_mmap_pgoff的实现。

ldo_mmap_pgoff

  1. unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
  2. unsigned long len, unsigned long prot,
  3. unsigned long flags, unsigned long pgoff,
  4. unsigned long *populate)
  5. {
  6. struct mm_struct * mm = current->mm;
  7. struct inode *inode;
  8. /*......*/
  9. /* Obtain the address to map to. we verify (or select) it and ensure
  10. * that it represents a valid section of the address space.
  11. */
  12. addr = get_unmapped_area(file, addr, len, pgoff, flags);
  13. if (addr & ~PAGE_MASK)
  14. return addr;
  15. /*......*/
  16. addr = mmap_region(file, addr, len, vm_flags, pgoff);
  17. /*......*/
  18. return addr;
  19. }

其意气风发函数首先通过 get_unmapped_area创建(或得到卡塔 尔(英语:State of Qatar)二个得休便休的vma,然后调用mmap_region对vma举行设置。我们切实看下mmap_region的实现。

lmmap_region

  1. unsigned long mmap_region(struct file *file, unsigned long addr,
  2. unsigned long len, vm_flags_t vm_flags, unsigned long pgoff)
  3. {
  4. struct mm_struct *mm = current->mm;
  5. struct vm_area_struct *vma, *prev;
  6. int correct_wcount = 0;
  7. int error;
  8. struct rb_node **rb_link, *rb_parent;
  9. unsigned long charged = 0;
  10. struct inode *inode = file ? file_inode(file) : NULL;
  11. /*......*/
  12. if (file) { /*假使不是无名氏映射*/
  13. if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
  14. goto free_vma;
  15. if (vm_flags & VM_DENYWRITE) {
  16. error = deny_write_access(file);
  17. if (error)
  18. goto free_vma;
  19. correct_wcount = 1;
  20. }
  21. vma->vm_file = get_file(file);
  22. error = file->f_op->mmap(file, vma); /*调用对应文件系统的mmap函数*/
  23. if (error)
  24. goto unmap_and_free_vma;
  25. addr = vma->vm_start;
  26. pgoff = vma->vm_pgoff;
  27. vm_flags = vma->vm_flags;
  28. } else if (vm_flags & VM_SHARED) { /*shared 无名氏映射*/
  29. if (unlikely(vm_flags & (VM_GROWSDOWN|VM_GROWSUP)))
  30. goto free_vma;
  31. error = shmem_zero_setup(vma);
  32. if (error)
  33. goto free_vma;
  34. } /*private 无名氏映射*/
  35. file = vma->vm_file;
  36. /*......*/
  37. }

要是传入了fd,则调用对应文件系统的mmap函数。以ext4文件系统为例。其mmap函数为 ext4_file_mmap。

lext4_file_mmap

  1. static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
  2. {
  3. struct address_space *mapping = file->f_mapping;
  4. if (!mapping->a_ops->readpage)
  5. return -ENOEXEC;
  6. file_accessed(file);
  7. vma->vm_ops = &ext4_file_vm_ops;
  8. return 0;
  9. }

能够看出这一个函数只是设置vma->vm_ops为眼下文件系统的管理函数。

  1. static const struct vm_operations_struct ext4_file_vm_ops = {
  2. .fault = filemap_fault,
  3. .page_mkwrite = ext4_page_mkwrite,
  4. .remap_pages = generic_file_remap_pages,
  5. };

倘假诺无名氏映射(不传播fd卡塔 尔(阿拉伯语:قطر‎,且传入了shared flag。则调用shmem_zero_setup。

lshmem_zero_setup

  1. int shmem_zero_setup(struct vm_area_struct *vma)
  2. {
  3. struct file *file;
  4. loff_t size = vma->vm_end - vma->vm_start;
  5. file = shmem_file_setup("dev/zero", size, vma->vm_flags);
  6. if (IS_ERR(file))
  7. return PTR_ERR(file);
  8. if (vma->vm_file)
  9. fput(vma->vm_file);
  10. vma->vm_file = file;
  11. vma->vm_ops = &shmem_vm_ops;
  12. return 0;
  13. }

能够看来此间将vma->vm_ops设置为tmpfs文件系统的shmem_vm_ops。

  1. static const struct vm_operations_struct shmem_vm_ops = {
  2. .fault = shmem_fault,
  3. #ifdef CONFIG_NUMA
  4. .set_policy = shmem_set_policy,
  5. .get_policy = shmem_get_policy,
  6. #endif
  7. .remap_pages = generic_file_remap_pages,
  8. };

全方位mmap函数的管理进度如下:

美高梅游戏官网网站 1

咱俩驾驭mmap函数只是为经过分配了虚构内部存款和储蓄器空间,并未真正创制设想内部存储器和物理内部存储器的映射。那些创设映射的长河是到缺页中断的函数中张开的。

缺页中断的管理进程大要如下:

美高梅游戏官网网站 2

  1. int handle_pte_fault(struct mm_struct *mm,
  2. struct vm_area_struct *vma, unsigned long address,
  3. pte_t *pte, pmd_t *pmd, unsigned int flags)
  4. {
  5. pte_t entry;
  6. spinlock_t *ptl;
  7. /*......*/
  8. entry = *pte;
  9. if (!pte_present(entry)) {
  10. if (pte_none(entry)) {
  11. if (vma->vm_ops)
  12. return do_linear_fault(mm, vma, address,
  13. pte, pmd, flags, entry);
  14. /*匿名private 映射*/
  15. return do_anonymous_page(mm, vma, address,
  16. pte, pmd, flags);
  17. }
  18. }
  19. return 0;
  20. }

我们看见vma->vm_ops时会调用do_anonymous_page。这里要求专一,有人见到函数名就感觉那是无名映射的逻辑,可是依据前边的代码剖析佚名shared的时候也是会安装vma->vm_ops的。独有大器晚成种状态不会设置,那正是无名氏private映射。

之所以综上,有以下结论:

(1卡塔 尔(英语:State of Qatar)非无名shared映射:调用文件分别文件系统的缺页函数;

(2卡塔 尔(英语:State of Qatar)非无名氏private映射:调用文件分别文件系统的缺页函数;

(3卡塔尔国无名shared映射:调用tmpfs文件系统的缺页函数;

(4)匿名private映射:do_anonymous_page管理缺页,也是当前唯一支持THP(透明大页卡塔 尔(英语:State of Qatar)的不二秘诀。

别的补充:其实大家常用的posix和systemV分享内部存款和储蓄器底层都以因此tmpfs实现的,详见

mmap实现解析本文不是介绍mmap函数的利用办法,而是深入分析其根本完成,相关应用方法国网球国际赛央月经有好多素材。Mmap的庐山面目目实际上就是...

本文由美高梅网址发布于美高梅游戏官网网站,转载请注明出处:mmap实现分析

上一篇:认识结构体,结构体在固件库中的应用 下一篇:没有了
猜你喜欢
热门排行
精彩图文