1. kmalloc的用法
kmalloc与malloc 相似,该函数返回速度快快(除非它阻塞)并对其分配的内存不进行 初始化(清零),
分配的区仍然持有它原来的内容, 分配的区也是在物理内存中连续
记住 kmalloc 原型是:
#include
void *kmalloc(size_t size, int flags);
给 kmalloc 的第一个参数是要分配的块的大小。 第2个参数, 分配标志, 用于控制 kmalloc的行为。
1.1. flags 参数
GFP_ATOMIC
用来从中断处理和进程上下文之外的其他代码中分配内存。 从不睡眠。
GFP_KERNEL
内核内存的正常分配。 可能睡眠。
GFP_USER
用来为用户空间页来分配内存; 它可能睡眠。
GFP_HIGHUSER
如同 GFP_USER, 但是从高端内存分配, 如果有。 高端内存在下一个子节描述。
GFP_NOIO
GFP_NOFS
这个标志功能如同 GFP_KERNEL, 但是它们增加限制到内核能做的来满足请求。 一个GFP_NOFS
分配不允许进行任何文件系统调用, 而 GFP_NOIO 根本不允许任何 I/O 初始化。 它们主要地用
在文件系统和虚拟内存代码, 那里允许一个分配睡眠, 但是递归的文件系统调用会是一个坏注意。
上面列出的这些分配标志可以是下列标志的相或来作为参数, 这些标志改变这些分配如何进行:
__GFP_DMA
这个标志要求分配在能够 DMA 的内存区。 确切的含义是平台依赖的并且在下面章节来解释。
__GFP_HIGHMEM
这个标志指示分配的内存可以位于高端内存。
__GFP_COLD
正常地, 内存分配器尽力返回"缓冲热"的页 -- 可能在处理器缓冲中找到的页。 相反, 这个标志
请求一个"冷"页, 它在一段时间没被使用。 它对分配页作 DMA 读是有用的, 此时在处理器缓冲中
出现是无用的。
__GFP_NOWARN
这个很少用到的标志阻止内核来发出警告(使用 printk ), 当一个分配无法满足。
__GFP_HIGH
这个标志标识了一个高优先级请求, 它被允许来消耗甚至被内核保留给紧急状况的最后的内存页。
__GFP_REPEAT
__GFP_NOFAIL
__GFP_NORETRY
这些标志修改分配器如何动作, 当它有困难满足一个分配。 __GFP_REPEAT 意思是" 更尽力些尝试"
通过重复尝试 -- 但是分配可能仍然失败。 __GFP_NOFAIL 标志告诉分配器不要失败; 它尽最大努
力来满足要求。 使用 __GFP_NOFAIL 是强烈不推荐的; 可能从不会有有效的理由在一个设备驱动中
使用它。 最后, __GFP_NORETRY 告知分配器立即放弃如果得不到请求的内存。
1.2. size 参数
内核管理系统的物理内存, 这些物理内存只是以页大小的块来使用。 结果是, kmalloc
看来非常不同于一个典型的用户空间 malloc 实现。一个简单的, 面向堆的分配技术可能很快有麻烦;
它可能在解决页边界时有困难。 因而, 内核使用一个特殊的面向页的分配技术来最好地利用系统RAM。
Linux 处理内存分配通过创建一套固定大小的内存对象池。 分配请求被这样来处理,进 入一个
持有足够大的对象的池子并且将整个内存块递交给请求者。
然而, 驱动开发者应当记住的一件事情是, 内核只能分配某些预定义的, 固定大小的字节数组。 如果你请求一个任意数量内存,你可能得到稍微多于你请求的, 至多是2倍数量。 同样, 程序员应当记住
kmalloc 能够处理的最小分配是 32 或者 64 字节,依赖系统的体系所使用的页大小。
kmalloc 能够分配的内存块的大小有一个上限。 这个限制随着体系和内核配置选项而 变化。
如果你的代码是要完全可移植,它不能指望可以分配任何大于128 KB。
2. kmalloc 与 vmalloc
vmalloc分配内存的时候逻辑地址是连续的,但物理地址一般是不连续的,适用 于
那种一下需要分配大量内存的情况,如insert模块的时候。这种分配方式性能不如kmalloc。
kmalloc分配内存是基于slab,因此slab的一些特性包括着色,对齐等都具备,性能较好。
物理地址和逻辑地址都是连续的。
阅读(5111) | 评论(0) | 转发(0) |