Chinaunix首页 | 论坛 | 博客
  • 博客访问: 36612
  • 博文数量: 11
  • 博客积分: 265
  • 博客等级: 二等列兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-03 12:48
文章分类
文章存档

2012年(11)

我的朋友

分类: LINUX

2012-09-14 15:56:10

内核中不连续页的分配
物理上连续映射是最好的,但并不是总能成功的使用,在分配一大块内存时,可能无法找到连续的内存块
在用户空间这个不是问题,因为普通进程设计为使用处理器的分页机制,这个会降低速度并占用TLB

在内核中也使用这样的技术,内核分配了其虚拟地址空间的一部分,用于建立连续映射
在IA32系统中,紧随直接映射的前892MB的物理内存,在插入的8MB安全隙之后,用于管理不连续的内存的区域,这一段具有线性地址空间的所有性质,分配到其中的页可以是物理内存的任意地方
每个vmalloc分配的子区域都是自包含的,与其他vmalloc子区域通过一个内存页分隔,该分隔也是防止不正确的内存访问

1 用vmalloc分配内存
vmalloc函数,内核代码使用其分配在虚拟内存中连续但是在物理内存中不一定连续的内存
使用vmalloc的最著名的实例是内核对模块的实现,模块可能在任何时候加载,如果模块数据比较多,那么无法保证有足够的连续的内存可用,vmalloc可以使用小块内存拼接出足够的内存
用于vmalloc的内存页总是必须映射在内核地址空间中,因此使用ZONE_HIGHMEM内存域的页要优于其他内存域
  • 数据结构
内核在管理虚拟内存中的vmalloc时,内核必须跟踪哪些子区域被使用,哪些是空闲的

  • 创建vm_area
在创建一个新的虚拟内存区之前,必须要找到一个适当的位置。
vm_area实例组成的一个链表,管理vmalloc区域中已经建立的各个子区域
  • 分配内存区
vmalloc发起对不连续的内存区的分配操作
实现分成三个部分:
首先在vmalloc地址空间找到一个适当的区域,接下来从物理内存中分配各个页,最后将这些页映射到vmalloc区域中,分配虚拟内存的工作就完成了

物理内存区域的分配:
如果显式的分配页帧的结点,则内核直接调用alloc_pages_node
否则使用alloc_page从当前结点分配页帧
分配的页从相关结点的伙伴系统中移除,内存通过参数指示内存管理子系统尽可能从ZONE_HIGHMEM内存域分配页帧
从伙伴系统分配内存时,是逐页分配,而不是一次分配一大块,这是vmalloc一个关键方面
如果可以确信能够分配连续内存区,那么就没有必要使用vmalloc,毕竟该函数的所有目的就是分配大的内存块,尽管内存碎片的缘故,内存块的页帧不可能是连续的

内核调用map_vm_area将分散的物理内存页连续映射到虚拟的vmalloc区域,该函数遍历所有的物理内存页,在各级页目录/页表中分配所需的目录项/表项

释放内存:
内核释放内存函数vfree,vunmap
上图是_vunmap的代码流程图
不必明确给出需要释放的区域长度,长度可以从vmlist中的信息导出
unmap_vm_area使用找到的vm_area实例,从页表删除不再需要的项,与分配内存相似,该函数需要操作各级页表
如果_vunmap的参数deallocation_pages设置为1,内核会遍历area->pages的所有元素,即指向所涉及的物理内存页的page实例的指针,将页释放到伙伴系统

最后,必须释放用于管理该内存区的内核数据结构
阅读(1188) | 评论(0) | 转发(0) |
0

上一篇:进程

下一篇:没有了

给主人留下些什么吧!~~