内核内存分配
在应用程序中,常使用malloc函数进行动态内存分配,而在Linux内核中,通常使用kmalloc来动态分配内存。
kmalloc 原型是:
#include <linux/slab.h>
void *kmalloc(size_t size, int flags)
参数:
size:要分配的内存大小。
flags:分配标志, 它控制 kmalloc 的行为。
1、最常用的标志是GFP_KERNEL(内部最终通过调用 __get_free_pages 来进行, 它是 GFP_ 前缀的来源),它的意思是该内存分配是由运行在内核态的进程调用的。
也就是说,调用它的函数属于某个进程的,当空闲内存太少时,kmalloc函数会使当前进程进入睡眠,等待空闲页的出现。
2、如果kmalloc是在进程上下文之外调用,比如在中断处理,任务队列处理和内核定时器处理中。这些情况属于中断上下文,不能进入睡眠,
这时应该使用优先权GFP_ATOMIC。
3、GFP_ATOMIC
用来在进程上下文之外的代码(包括中断处理)中分配内存,从不睡
眠。
4、GFP_KERNEL
进程上下文中的分配。可能睡眠。(16M-896M)
5、__GFP_DMA
这个标志要求分配能够 DMA 的内存区(物理地址在16M以下的页
帧 )
6、__GFP_HIGHMEM
这个标志表示分配的内存位于高端内存。(896M以上)
用kfree函数来释放kmalloc分配的内存
如果模块需要分配大块的内存,那使用面向页的分配技术会更好
get_zeroed_page(unsigned int flags)
返回指向新页面的指针,并将页面清零。
__get_free_page(unsigned int flags)
和get_free_page类似,但不清零页面。
__get_free_pages(unsigned int flags,unsigned int order )
分配若干个连续的页面,返回指向该内存区域的指针,但也不清零这段内存区域。
当程序用完这些页, 可以使用下列函数之一来释放它们:
void free_page(unsigned long addr)
void free_pages(unsigned long addr, unsigned
long order)
如果释放的和先前分配数目不等的页面,会导致系统错误