内存管理API之vmalloc

void *vmalloc(unsigned long size)用于分配一段虚拟地址联系的内存,注意这里只保证虚拟地址连续,
不能保证物理地址连续.
其源码分析如下:
void *vmalloc(unsigned long size)
{
	return __vmalloc_node_flags(size, NUMA_NO_NODE,
				    GFP_KERNEL);
}
添加flags后调用__vmalloc_node_flags
static inline void *__vmalloc_node_flags(unsigned long size,
					int node, gfp_t flags)
{
	return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
					node, __builtin_return_address(0));
}
这里__builtin_return_address(0)保存的是__vmalloc_node_flags的地址
static void *__vmalloc_node(unsigned long size, unsigned long align,
			    gfp_t gfp_mask, pgprot_t prot,
			    int node, const void *caller)
{
	return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
				gfp_mask, prot, 0, node, caller);
}
从这里可以知道虚拟地址在VMALLOC_START~VMALLOC_END 之间
void *__vmalloc_node_range(unsigned long size, unsigned long align,
			unsigned long start, unsigned long end, gfp_t gfp_mask,
			pgprot_t prot, unsigned long vm_flags, int node,
			const void *caller)
{
	struct vm_struct *area;
	void *addr;
	unsigned long real_size = size;
	#从这里可以知道vmalloc 申请的虚拟地址也是页page 对齐的
	size = PAGE_ALIGN(size);
	#size 为零或者size 超过最大的size ,则退出,从这里知道最大的size 等于totalram_pages
	if (!size || (size >> PAGE_SHIFT) > totalram_pages)
		goto fail;
	#申请一个struct vm_struct *area的机构体内存
	area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED |
				vm_flags, start, end, node, gfp_mask, caller);
	if (!area)
		goto fail;
		
	#申请虚拟连续的内存
	addr = __vmalloc_area_node(area, gfp_mask, prot, node);
	if (!addr)
		return NULL;

	/*
	 * In this function, newly allocated vm_struct has VM_UNINITIALIZED
	 * flag. It means that vm_struct is not fully initialized.
	 * Now, it is fully initialized, so remove this flag here.
	 */
	#清除VM_UNINITIALIZED 标志
	clear_vm_uninitialized_flag(area);
	#用于检测vmalloc 内存泄漏
	kmemleak_vmalloc(area, size, gfp_mask);
	#返回申请到大小为size的虚拟地址
	return addr;

fail:
	#失败的话,打印log,并返回null地址
	warn_alloc(gfp_mask, NULL,
			  "vmalloc: allocation failure: %lu bytes", real_size);
	return NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值