良许Linux教程网 干货合集 Linux 内存管理之vmalloc

Linux 内存管理之vmalloc

走进vmalloc

根据前面的系列文章,我们知道了buddy system是基于页框分配器,kmalloc是基于slab分配器,而且这些分配的地址都是物理内存连续的。但是随着碎片化的积累,连续物理内存的分配就会变得困难,对于那些非DMA访问,不一定非要连续物理内存的话完全可以像malloc那样,将不连续的物理内存页框映射到连续的虚拟地址空间中,这就是vmap的来源)(提供把离散的page映射到连续的虚拟地址空间),vmalloc的分配就是基于这个机制来实现的。

vmalloc最小分配一个page,并且分配到的页面不保证是连续的,因为vmalloc内部调用alloc_page多次分配单个页面。

vmalloc的区域就是在上图中VMALLOC_START – VMALLOC_END之间,可通过/proc/vmallocinfo查看。

数据结构

  • vmap_area 描述一段虚拟地址的区域,可以将struct vm_struct构成一个链表,维护多段映射。
struct vmap_area {
 unsigned long va_start; //vmalloc申请虚拟地址返回的起始地址
 unsigned long va_end; //vmalloc申请申请虚拟地址返回的结束地址
 unsigned long flags;
  //挂接到vmap_area_root红黑树
 struct rb_node rb_node;         /* address sorted rbtree */
  //挂接到vmap_area_list链表
 struct list_head list;          /* address sorted list */
 struct llist_node purge_list;    /* "lazy purge" list */
 //如果当前VA处于使用状态(即在vmap_area_root为根的红黑树中和vmap_area_list链表中),vm有效,指向用于

管理虚拟地址和物理页之间的映射关系的描述符
 struct vm_struct *vm;
 struct rcu_head rcu_head;
};
  • vm_struct 管理虚拟地址和物理页之间的映射关系
struct vm_struct {
 struct vm_struct *next; //指向下一个vm结构体
 void   *addr; //当前vmalloc区域的虚拟地址的起始地址
 unsigned long  size; //当前vmalloc区域的虚拟地址的大小
 unsigned long  flags;
 //vamlloc分配获取的各个物理页面并是不连续的,每个物理页面用struct page描述,一个vm_struct对用到的管

理所有物理页面的struct page构成一个数组,而pages就是指向这个数组的指针。
 struct page  **pages;
 unsigned int  nr_pages; //vmalloc映射的page数目
 phys_addr_t  phys_addr; //用来映射硬件设备的IO共享内存,其他情况下为0
 const void  *caller; //调用vmalloc函数的函数的地址
};

vmalloc

主要分以下三步:

  1. 从VMALLOC_START到VMALLOC_END查找空闲的虚拟地址空间(hole)
  2. 根据分配的size,调用alloc_page依次分配单个页面.
  3. 把分配的单个页面,映射到第一步中找到的连续的虚拟地址。把分配的单个页面,映射到第一步中找到的连续的虚拟地址。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部