linux内核内存分配函数kmalloc()、kzalloc()、vmalloc()与__get_free_page()

目录

1、值得注意的点

2、函数原型

2.1 kmalloc()与kfree()

2.2 kzalloc与kfree()

2.3 vmalloc与vfree()

2.4 __get_free_page()与free_pages()

2.5 __get_free_pages()与free_pages()

2.6 get_zeroed_page()


1、值得注意的点

1、内核把物理作为内存管理的基本单位,尽管处理器的最小寻址单位通常为字(或者为字节),但是MMU(内存管理单元)通常以页为单位进行处理。从虚拟内存的角度看,页就是最小单位。

2、kmalloc()和__get_free_page()等类似函数,申请的内存位于DMA和常规区域的映射区,而且在物理上也是连续的。vmalloc()申请的物理地址不一定是连续的。

3、kmalloc()使用GFP_KERNEL标志申请内存时,若暂时不能满足,则进程会休眠等待页,即会引起阻塞,因此不能在中断上下文或者持有自旋锁时使用GFP_KERNEL申请内存。应当使用GFP_ATOMIC标志来申请内存,若不存在空闲页,直接返回。
vmalloc()申请内存的过程中可以睡眠,因此不能用于中断上下文中。

4、一般来说,为了性能,通常使用kzalloc()/kmalloc()分配内存,如果要分配的内存过大则使用vmalloc()
什么时候使用什么标志
情况标志
进程上下文,可以睡眠

GFP_KERNEL

进程上下文,不可以睡眠GFP_ATOMIC,在睡眠前或者睡眠后可以使用GFP_KERNEL进行分配内存
中断处理函数 GFP_ATOMIC
软中断GFP_ATOMIC
taskletGFP_ATOMIC
需要用于DMA内存,可以睡眠GFP_DMA | GFP_KERNEL
需要用于DMA内存,不可以睡眠GFP_DMA | GFP_ATOMIC,在睡眠前可以使用GFP_KERNEL进行分配内存

2、函数原型

2.1 kmalloc()与kfree()

void *kmalloc(size_t s, gfp_t gfp)
/*
功能:分配对应的虚拟内存
参数:@size:分配内存区的大小,以字节为单位
     @flags:内存分配标志
          GFP_KERNEL:内核可能被休眠,用于进程上下文中
          GFP_ATOMIC:处理紧急的事务,用在中断上下文
          GFP_DMA:给DMA分配内存时使用,使用该标志时分配的虚拟地址和物理地址都是连续的
返回值:对应虚拟地址
特点:最大128k , 分配虚拟地址,其虚拟地址空间连续,
      物理地址空间也是连续,分配的内存必须是2的次幂的形式
*/

void kfree(const void *ptr)
/*
功能:释放对应的虚拟内存
参数:
    @ptr:虚拟内存的起始地址
返回值:无
*/

2.2 kzalloc与kfree()

static inline __alloc_size(1) void *kzalloc(size_t size, gfp_t flags)
{
	return kmalloc(size, flags | __GFP_ZERO);
}
kzalloc = kmalloc+memset(,0,):分配虚拟内存区并清零

void kfree(const void *ptr)
/*
功能:释放对应的虚拟内存
参数:
    @ptr:虚拟内存的起始地址
返回值:无
*/

2.3 vmalloc与vfree()

void *vmalloc(unsigned long size)
/*
功能:分配对应的虚拟内存
参数:
    @size:分配内存区的大小
返回值:对应虚拟地址
特点:分配虚拟地址,其虚拟地址空间连续,
        但是物理地址空间不一定连续
*/

void vfree(const void *addr)
/*
功能:释放对应的虚拟内存
参数:
    @addr:虚拟内存区的首地址
*/

2.4 __get_free_page()与free_pages()

unsigned long __get_free_page(gfp_t gfp)
/*
功能:分配一个页的内存 4K
*/

void free_page(unsigned long addr)
/*
功能:释放一个页的内存
*/

2.5 __get_free_pages()与free_pages()

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
/*
功能:分配 2的order次方 的内存,如 order=3,即分配8个页 
order-->2^n :第二个参数填写的是n
n = get_order(5500)
*/

void free_pages(unsigned long addr, unsigned int order)
/*
功能:释放多个页的内存
*/

2.6 get_zeroed_page()

unsigned long get_zeroed_page(gfp_t gfp_mask)
/*
功能:只分配一页,让其内容填充0
*/
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值