【原创】(十二)Linux内存管理之vmap与vmalloc
背景
Read the fucking source code!
--By 鲁迅A picture is worth a thousand words.
--By 高尔基
说明:
- Kernel版本:4.14
- ARM64处理器,Contex-A53,双核
- 使用工具:Source Insight 3.5, Visio
1. 概述
在之前的系列文章中,分析到了Buddy System
的页框分配,Slub分配器
的小块内存对象分配,这些分配的地址都是物理内存连续的。当内存碎片后,连续物理内存的分配就会变得困难,可以使用vmap
机制,将不连续的物理内存页框映射到连续的虚拟地址空间中。vmalloc
的分配就是基于这个机制来实现的。
还记得下边这张图吗?
vmap/vmalloc
的区域就是在VMALLOC_START ~ VMALLOC_END
之间。
开启探索之旅吧。
2. 数据结构
2.1 vmap_area/vm_struct
这两个数据结构比较简单,直接上代码:
struct vm_struct { struct vm_struct *next; void *addr; unsigned long size; unsigned long flags; struct page **pages; unsigned int nr_pages; phys_addr_t phys_addr; const void *caller; }; struct vmap_area { unsigned long va_start; unsigned long va_end; unsigned long flags; struct rb_node rb_node; /* address sorted rbtree */ struct list_head list; /* address sorted list */ struct llist_node purge_list; /* "lazy purge" list */ struct vm_struct *vm; struct rcu_head rcu_head; };
struct vmap_area
用于描述一段虚拟地址的区域,从结构体中va_start/va_end
也能看出来。同时该结构体会通过rb_node
挂在红黑树上,通过list
挂在链表上。struct vmap_area
中vm
字段是struct vm_struct
结构,用于管理虚拟地址和物理页之间的映射关系,可以将struct vm_struct
构成一个链表,维护多段映射。
关系如下图: