深入理解linux内核--8内存管理
页描述符
内核必须记录每个页框的当前状态。所有的页描述符放在mem_map数组中。因为描述符长度是32字节,
所以mem_map所需的空间略小于整个RAM的1%.
非一致内存访问(NUMA)
这种模型中,给定CPU对不同内存单元的访问时间可能不一样。
请求和释放页框
alloc_pages(gfp_mask, order)
:用这个函数请求2 order次方个连续的页框,它返回第一个所分配页框描述符的地址。
alloc_page(gfp_mask)
获得一个单独的页框
__get_free_pages(gfp_mask, order)
:类似alloc_pages(gfp_mask, order),但它返回第一个所分配页的线性地址。
gfp_mask是一组标志,它指明了如何寻址空闲的页框:
__GFP_DMA:所请求的页框必须处于ZONE_DMA的管理区,等价与GFP_DMA
__GFP_HIGHMEM:所请求的页框处于ZONE_HIGHMEM管理区
__GFP_WAIT:允许内核对等待空闲页框的当前进程进程阻塞
高端内存页框的内核映射
与直接映射的物理内存末端,高端内存的始端所对应的线性地址存放在high_memory变量中,它被设置为896MB
896MB边界以上的页框并映射在内核线性地址空间的第4GB,内核不能直接访问。
也就是说_get_free_page(GFP_HIGHMEM,0)在高端内存分配了一个页框后,但是不能返回它的线性地址,因为它根本就不存在。
注意,在64位硬件平台不存在这个问题,因为线性地址空间远大于所安装的RAM
- 高端内存的页框分配只能通过alloc_pages()、alloc_page(),这些函数返回被分配页框的页描述符的线性的地址。所有页描述符一旦被分配在低端内存中,它就不会改变。
- 没有线性地址的高端内存中的页框就不能被内核访问,因此,内核线性地址空间的最后128MB中的一部分专门用于映射高端内存页框。:永久内核映射、临时内核映射、以及非连续内存映射。
内存区管理
伙伴系统采用页框作为基本内存区,适合大块内存请求,如果几十几百字节,分配一个整页框就是浪费。
所以用内碎片这一数据结构描述小内存区。
slab分配器