linux kmalloc函数
来源:互联网 发布:242家网络小额贷款牌照 编辑:程序博客网 时间:2024/06/07 05:45
static inline void *kmalloc(size_t size, int flags)
{
if (__builtin_constant_p(size)) {
int i = 0;
#define CACHE(x)
if (size <= x)
goto found;
else
i++;
#include "kmalloc_sizes.h"
#undef CACHE
{
extern void __you_cannot_kmalloc_that_much(void);
__you_cannot_kmalloc_that_much();
}
found:
return kmem_cache_alloc((flags & GFP_DMA) ?
malloc_sizes[i].cs_dmacachep : malloc_sizes[i].cs_cachep, flags);
}
return __kmalloc(size, flags);
}
上面的代码是2.6内核下的kmalloc函数定义,对比2.4的内核,该函数被移到了linux/slab.h头文件中作为一个static inline函数实现,所以在调用该函数时,一定要包含linux/slab.h. kmalloc是基于slab实现的,分配的内存不能超过128k, 并且实际上每次分配的内存大小都是2的幂次.
这里只介绍一下上面代码中的那个__you_cannot_kmalloc_that_much()函数,这个函数实际上并没有定义,但是编译连接(insmod)都不会有问题,是一个很有趣的用法. 先看__builtin_constant_p(),这是gcc的内建函数,可以判断它的参数在编译时是否为常量,若是,返回值为真,否则为假,凡是通过gcc编译的c代码中都可以直接引用这一类以__builtin_打头的函数.下面的include展开的结果如下:
if (size <= 32)
goto found;
else
i++;
if (size <= 64)
goto found;
else
i++;
..............
..............
if (size <= 131072)
goto found;
else
i++;
如果size在编译时就能确定出它的大小,编译器就可以充分发挥他的优化能力,把无关代码删掉,比如size小于131072时,整个函数只剩下一个return语句了,__you_cannot_kmalloc_that_much的调用也被删掉了,所以在连接时不会有问题,否则在insmod模块的时候会告诉你该符号没有定义,这说明你给的参数size大于了128k. 这实际上是在编译连接时做了参数范围的检查,这个用法真得不多见.
kmalloc引入的目的:
内核为了提高一些常用的数据结构(一般大小远小于1个page)的内存使用效率(空间和时间上),引入slab分配器(区别于伙伴系统算法),slab分配器使用伙伴系统算法作为物理内存分的接口,但是对于slab分配器中的对象,内核释放这个对象之后,相应的物理内存并不释放,可以留给下一个可能的对象使用,这样可以提高经常使用的数据结构内存使用效率(否则导致内存碎片和让内核疲劳于不停的内存分配和释放)。对于每种常用的数据结构(比如skb_buff),内核可以使用kmem_cache_create()创建一个专用的高速缓存,但是如果对这个存储区的请求并不是那么的频繁,可以考虑使用kmalloc从通用高速缓存分配按照几何分布的存储区(从32个字节,到128k)。
vmalloc引入的目的:
系统对于物理内存的分配最终通过伙伴系统的alloc_pages实现,一般把存储区映射到一组连续的页框,但是这样无疑会引入外碎片,对于这些外碎片应该是加以合理的利用,于是引入非连续存储区的管理,非连续的存储区中非连续主要是强调物理上的非连续,但是线性地址是连续,这些线性地址是在3G+mem+8M以上地址空间中分配和管理的。
固定映射的线性地址存放在线性地址的第四个GB的末端,它是一个索引对应一个页框及其线性地址,通过索引寻找到这个线性地址,据说对于指针变量效率会更高。
其实kmalloc和vmalloc并没有太多的联系,vmalloc会调用kmalloc分配非连续线性区描述这样的对象,但他们最终都通过伙伴系统算法作为接口分配内存。
* %GFP_USER - Allocate memory on behalf of user. May sleep. * * %GFP_KERNEL - Allocate normal kernel ram. May sleep. * * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools. * For example, use this inside interrupt handlers. * * %GFP_HIGHUSER - Allocate pages from high memory. * * %GFP_NOIO - Do not do any I/O at all while trying to get memory. * * %GFP_NOFS - Do not make any fs calls while trying to get memory. * * %GFP_NOWAIT - Allocation will not sleep. * * %GFP_THISNODE - Allocate node-local memory only. * * %GFP_DMA - Allocation suitable for DMA. * Should only be used for kmalloc() caches. Otherwise, use a * slab created with SLAB_DMA.
- linux kmalloc函数
- linux kmalloc函数分析
- linux中kmalloc函数详解
- linux内核kmalloc函数使用方法
- kmalloc函数
- Linux kmalloc
- [linux 内核]kmalloc/kfree,vmalloc/vfree函数用法和区别
- kmalloc内核函数
- kmalloc函数详解
- Linux内核学习:kmalloc
- kmalloc linux内存管理
- linux kmalloc()和__get_free_pages()
- Linux 内存管理: Kmalloc
- linux kmalloc fail info
- 内核中的kmalloc函数详解
- 内核中的kmalloc函数详解
- kzalloc和kmalloc函数详解
- 内核中的kmalloc函数详解
- Hbase配置时出错处理
- Ajax实现添加、修改和删除提示
- DX着色
- MYSQL联接类型
- AndEngine之DEMO学习(八)EntityModifierIrregularExample
- linux kmalloc函数
- kettle 查询 存储过程
- 组合模式(Composite Pattern)
- Objective-C 编程语言官网文档(一)-简介
- axis实现webservices 实例
- OpenGL error LNK2001
- 完全卸载sql server2008
- 高级套接字函数 fcntl 设置socket 非阻塞
- 检测C++的内存泄漏