Linux内核内存分配函数之kmalloc

Linux内核内存分配函数之kmalloc,第1张

本文介绍Linux内核内存分配函数 kmalloc 。

注:

1) __builtin_constant_p 编译器内联函数,判断传入参数是否为常量。如果是变量,直接调用 __kmalloc 函数。

2) KMALLOC_MAX_CACHE_SIZE 表示系统创建 slab cache 的最大值为8K,定义如下:

RockPI 4A Linux内核使能 ARM64_4K_PAGES 。可使用命令 getconf 查看 page size ,具体如下:

3) kmalloc 一般用于小内存分配,RockPI 4A Linux内核基于 slub ( CONFIG_SLUB=y )实现。系统先用页分配器分配以页为最小单位的连续物理地址,然后 kmalloc 在此基础上根据调用者的需要进行切分。如果分配超过 KMALLOC_MAX_CACHE_SIZE ,则使用 kmalloc_large 进行大内存分配,即调用页分配器分配内存。( 后续仔细学习

4) kmalloc 分配的内存在物理上连续,可用于DMA设备。 vmalloc 分配的内存是线性地址连续,物理地址不连续,不可用于DMA设备。

size :分配内存的大小,以字节为单位;

flags :分配内存的类型,包括:

1) GFP_USER :可能会引起休眠,用于为用户空间分配内存。

2) GFP_KERNEL :可能会引起休眠,用于内核内存正常分配。

3) GFP_ATOMIC :不会引起休眠,可用于中断处理程序中内存分配。

4) GFP_HIGHUSER :从高端内存中分配内存。

5) GFP_DMA :用于DMA内存分配。

6)其它类型见: include/linux/gfp.h

GFP 可理解为 get free page 。

返回分配内存的首地址,是虚拟地址(线性地址)。

正所谓有借有还,再借不难。每次 kmalloc ,都要有对应的内存释放函数 kfree 。定义文件: mm/slub.c ,如下:

linux系统用户空间中动态申请内存的函数为malloc (),这个函数在各种 *** 作系统上的使用都是一致的,malloc ()申请的内存的释放函数为free()。对于Linux而言,C库的malloc ()函数一般通过brk ()和mmap ()两个系统调用从内核申请内存。由于用户空间C库的malloc算法实际上具备一个二次管理能力,所以并不是每次申请和释放内存都一定伴随着对内核的系统调用。比如,代码清单11.2的应用程序可以从内核拿到内存后,立即调用free(),由于free()之前调用了mallopt(M_TRIM_THRESHOLD,一1)和mallopt (M_MMAP_MAX,0),这个free ()并不会把内存还给内核,而只是还给了C库的分配算法(内存仍然属于这个进程),因此之后所有的动态内存申请和释放都在用户态下进行。另外,Linux内核总是采用按需调页(Demand Paging),因此当malloc ()返回的时候,虽然是成功返回,但是内核并没有真正给这个进程内存,这个时候如果去读申请的内存,内容全部是0,这个页面的映射是只读的。只有当写到某个页面的时候,内核才在页错误后,真正把这个页面给这个进程。在Linux内核空间中申请内存涉及的函数主要包括kmalloc( ) 、get free pages ( )和vmalloc ()等。kmalloc ()和_get_free pages ()(及其类似函数)申请的内存位于DMA和常规区域的映射区,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系。而vmalloc()在虚拟内存空间给出一块连续的内存区,实质上,这片连续的虚拟内存在物理内存中并不一定连续,而vmalloc ()申请的虚拟内存和物理内存之间也没有简单的换算关系。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7466803.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-06
下一篇 2023-04-06

发表评论

登录后才能评论

评论列表(0条)

保存