最近在进行Linux内核编程的时候使用到了kmalloc用于申请内存,kmalloc与mlloc相似,用于获取一段连续的内存空间,其不会对获取到的内存空间清零。
kmlloc的原型是void *kmalloc(size_t size, int flags); 第一个参数size表示要分配的内存大小,第二个参数这是分配标志。之前使用的时候对第二个参数并没有太关注,以为只是固定的填写GFP_KERNEL,直到无意中看到别人写的代码中有时填写了其它值才去查阅了资料详细学习了一下。
首先先看一下最常用的GFP_KERNEL,它表示内存分配是由运行在内核空间的进程执行的,也就是调用它的函数正代表某个进程执行系统调用。GFP_KERNEL表示允许kmalloc在空闲内存较少的时候把当前进程转入休眠以等待一个页面,因此,使用GFP_KERNEL申请内存的函数必须是可重入的。
GFP_ATOMIC是另一个重要的标志,其主要用于中断处理例程或者其它运行在进程上下文之外的代码中分配内存,它不会休眠。内核中通常会为原子性的分配预留一些空闲页面,使用该标志时,kmalloc甚至可以用掉最后一个空闲页面。
除了这两种常用的标志外,还有GFP_USER(用于为用户空间分配内存,可能会休眠),GFP_HIGHUSER(与GFP_USER类似,存在高端内存时从高端内存中分配),GFP_NOIO(与GFP_KERNEL类似,不允许IO的初始化),GFP_NOFS(与GFP_KERNEL类似,不允许执行文件系统调用),这些标志都用于一些特定的场景下,使用频率远远没有上两个大。