进程所拥有的所有线性区是使用两种结构进行管理的:
(1) 在一个单链表上(开始于mm_struct->map,按起始地址以递增顺序进行排列)
(2) 在一棵红黑树上,根节点位于mm_struct->rb。
内核频繁执行的一个操作就是查找包含指定线性地址的线性区。设一个进程有n个线性区,那么该操作在单链表上的执行时间复杂度是O(n),而在红黑树上是O(logn),这就是红黑树被使用的意义。一般来说,红黑树用来确定含有指定线性地址的线性区,而链表通常在扫面整个线性区集合时使用。
vm_area_struct描述符
struct vm_area_struct {
structmm_struct * vm_mm; /* 反向指针,指向该区域所属的mm_struct*/
unsignedlong vm_start; /*指定了该区域在用户空间中的起始地址*/
unsignedlong vm_end; /*指定了该区域在用户空间中的结束地址*/
structvm_area_struct *vm_next; /*维护单链表结构,按起始地址以递增顺序进行排列*/
struct rb_nodevm_rb; /*维护红黑树*/
pgprot_tvm_page_prot; /* 线性区中页框的访问许可权*/
unsignedlong vm_flags; /*线性区的标志*/
/*
*用于从文件到进程的虚拟地址空间的映射的反向查询:
*给出文件的一个区间,内核有时需要知道该区间映射到的所有进程。
*这种映射叫做共享映射。典型的例子是几乎每个进程对C标准库的使用。
*为了实现这种反向查询,所有的vm_area_struct都通过一个
*由shared维护的优先树管理。
*/
union{
struct{
structlist_head list;
void*parent; /*与prio_tree_node的parent成员在内存中位于同一个位置*/
structvm_area_struct *head;
}vm_set;