第7章掌握内存.docVIP

  • 1
  • 0
  • 约1.07万字
  • 约 9页
  • 2016-09-26 发布于天津
  • 举报
第7章掌握内存.doc

第7章 获取内存 到目前为止,我们总是用kmalloc和kfree来进行内存分配。当然,只用这些函数的确是管理内存的捷径。本章将会介绍其他一些内存分配技术。但我们目前并不关心不同的体系结构实际上是如何进行内存管理的。因为内核为设备驱动程序提供了一致的接口,本章的模块都不必涉及分段,分页等问题。另外,本章我也不会介绍内存管理的内部细节,这些问题将留到第13章“Mmap和DMA”的“Linux的内存管理”一节讨论。 kmalloc函数的内幕 kmalloc内存分配引擎功能强大,由于和malloc函数很相似,很容易就可以学会。这个函数运行得很快-一除非它被阻塞-一它不清零它获得的内存空间;分配给它的区域仍存放着原有的数据。在下面几节,我会详细介绍kmalloc函数,你可以将它和我后面要介绍的一些内存分配技术作个比较。 优先权参数 kmalloc函数的第一个参数是size(大小),我留在下个小节介绍。第二个参数,是优先权,更有意思,因为它会使得kmalloc函数在寻找空闲页较困难时改变它的行为。 最常用的优先权是GFP_KERNEL,它的意思是该内存分配(内部是通过调用get_free_pages来实现的,所以名字中带GFP)是由运行在内核态的进程调用的。也就是说,调用它的函数属于某个进程的,使用GFP_KERNEL优先权允许kmalloc函数在系统空闲内存低于水平线min_free_pages时延迟分配函数的返回。当空闲内存太少时,kmalloc函数会使当前进程进入睡眠,等待空闲页的出现。 新的页面可以通过以下几种途径获得。一种方法是换出其他页;因为对换需要时间,进程会等待它完成,这时内核可以调度执行其他的任务。因此,每个调用kmalloc(GFP_KERNEL)的内核函数都应该是可重入的。关于可重入的更多细节可见第5章“字符设备驱动程序的扩展操作”的“编写可重入的代码”一节。 并非使用GFP_KERNEL优先权后一定正确;有时kmalloc是在进程上下文之外调用的-一比如,在中断处理,任务队列处理和内核定时器处理时发生。这些情况下,current进程就不应该进入睡眠,这时应该就使用优先权GFP_ATOMIC。原子性(atomic)的内存分配允许使用内存的空闲位,而与min_free_pages值无关。实际上,这个最低水平线值的存在就是为了能满足原子性的请求。但由于内核并不允许通过换出数据或缩减文件系统缓冲区来满足这种分配请求,所以必须还有一些真正可以获得的空闲内存。 为kmalloc还定义了其他一些优先权,但都不经常使用,其中一些只在内部的内存管理算法中使用。另一个值的注意的优先权是GFP_NFS,它会使得NFS文件系统缩减空闲列表到min_free_pages值以下。显然,为使驱动程序“更快”而用GFP_NFS优先权取代GFP_KERNEL优先权会降低整个系统的性能。 除了这些常用的优先权,kmalloc还可以识别一个位域:GFP_DMA。GFP_DMA标志位要和GFP_KERNEL和GFP_ATOMIC优先权一起使用来分配用于直接内存访问(DMA)的内存页。我们将在第13章的“直接内存访问”一节讨论如何使用这个标志位。 size参数 系统物理内存的管理是由内核负责的,物理内存只能按页大小进行分配。这就需要一个面向页的分配技术以取得计算机内存管理上最大的灵活性。类似malloc函数的简单的线性的分配技术不再有效了;在象Unix内核这样的面向页的系统中内存如果是线性分配的就很难维护。空洞的处理很快就会成为一个问题,会导致内存浪费,降低系统的性能。 Linux是通过维护页面池来处理kmalloc的分配要求的,这样页面就可以很容易地放进或者取出页面池。PAGE_SIZE字节数大小的内存分配请求,fs/kmalloc.c文件维护页面簇的列表。每个页面簇都存放着连续若干页,可用于DMA分配。在这里我不介绍底层的实现细节,因为内部的数据结构可以在不影响分配语义和驱动程序代码的前提下加以改变。事实上,2.1.38版已经将kmalloc重新实现了。2.0版的内存分配实现代码可以参见文件mm/malloc.c,而新版的实现在文件mm/slab.c中。想了解2.0版实现的详情可参见第16章“内核代码的物理布局”的“分配和释放”一节。 Linux所使用的分配策略的最终方案是,内核只能分配一些预定义的固定大小的字节数组。如果你申请任意大小的内存空间,那么很可能系统会多给你一点。 这些预定义的内存大小一般“稍小于2的某次方”(而在更新的实现中系统管理的内存大小恰好为2的各次方)。如果你能记住这一点,就可以更有效地使用内存了。例如,如果在Linux 2.0上你需要一个2000字节左右的缓冲区,你最好还是

文档评论(0)

1亿VIP精品文档

相关文档