vmalloc
分配小块内存。实例化vmalloc内存分配器的核心数据描述符 vmap_area|vm_struct|pages,为 vmalloc 的工作提供内存基础。分配合适的虚拟内存区间 hole 从空闲红黑树找到合适大小的hole,隔离分配给 vmalloc
分配物理内存。调用alloc_page系列函数,从buddy 0 阶每次分配1页物理内存,直到分配满足需求为止。
更新页表映射。将物理内存与虚拟内存一一建立映射,然后返回虚拟起始地址给用户,完成分配动作
kmalloc
#include <linux/slab.h>
void *kmalloc(size_t size , int flags); //使用kfree();释放内存
其中flags参数有必要讲一下:一般代码中会用GFP_KERNEL和GFP_ATOMIC两种。
GFP_KERNEL 常规的分配标志,可能会阻塞,但并不是始终使用。
GFP_ATOMIC 这个标志用在中断处理程序、下半部、持有自旋锁以及其他不能睡眠的地方。
注意:kmalloc能够分配的内存块大小,存在一个上限。
两者区别
1、 vmalloc()分配的内存虚拟地址是连续的,而物理地址无须连续。而kmalloc()确保页在物理地址上是连续的,自然虚拟地址也是连续的。硬件设备用的的任何内存区都必须是物理上连续的块,而不仅仅是虚拟地址连续上的块。
2、 vmalloc()相比较于kmalloc()效率不高,因为获得的页必须转换为虚拟地址空间上连续的页,必须专门建立页表项。
3、 vmalloc()仅在不得已时才使用——典型的就是为了申请大块内存。该函数可能睡眠,因此不能从终端上下文中调用,也不能从其他不允许阻塞的情况下进行调用。