您的位置:首页 > 其它

内核态用vmalloc申请大块内存

2012-08-06 16:21 211 查看
转载地址:http://www.diybl.com/course/6_system/linux/Linuxjs/20091020/179581.html

内核态用vmalloc申请大块内存
    

作者:Godbach
2009年10月16日
       本文欢迎自由转载,请标明出处,并保证本文的完整性。

经常在内核版看到网友发帖,问如何在内核态申请大块内存,上百兆甚至上G的内存。用kmalloc或get_free_pages都不能满足这样的要求。今天又在内核版看到这样的帖子,其中白金兄回复说可以用vmalloc实现,并且给出了例程。本人也进行了实践,初步看来是分配成功了,但至于是否可以有效的应用于生产环境还有待于验证。本文的总结仅作为学习环境上的探讨和时间。
以下是申请大块内存的代码。代码是以白金兄提供的代码(http://linux.chinaunix.net/bbs/viewthread.php?tid=1139485&page=2#pid7139143)为蓝本,本人仅添加了传递模块参数的代码。传递的模块参数为申请内存的大小,单位为Mbyte。

#include <linux/module.h>
#include <linux/vmalloc.h>
 
MODULE_AUTHOR("platinum");
MODULE_DESCRIPTION("This is a module sample.");
MODULE_LICENSE("GPL");
 
/*Godbach added module parameter*/
static int memsize = 100;/*Unit: Mbyte*/
module_param(memsize, int, S_IRUGO);
__u8 *data;
 
int
init_module (void)
{
        data = vmalloc(1024 * 1024 * memsize);
 
        if (!data)
                return -ENOMEM;
 
        memset(data, 0xff, 1024 * 1024 * memsize);
        printk("module loaded.\n");
        return 0;
}
 
 
void
cleanup_module(void)
{
        vfree(data);
        printk("module unloaded.\n");
}
本人的内核版本是2.6.18.3。编译该内核模块,生成alloc_large_mem.ko.
以下是默认申请100M内存时系统前后内存的变化。
[root@localhost alloc_large_mem]# free

             total       used       free     shared    buffers     cached

Mem:        385624     188760     196864          0       1908      54936

-/+ buffers/cache:     131916     253708

Swap:       522104       8068     514036

[root@localhost alloc_large_mem]# insmod alloc_large_mem.ko 

[root@localhost alloc_large_mem]# free

             total       used       free     shared    buffers     cached

Mem:        385624     290388      95236          0       1960      54948

-/+ buffers/cache:     233480     152144

Swap:       522104       8068     514036

[root@localhost alloc_large_mem]#
由此可见,insmod模块之后系统使用的内粗增加了100M多一点。
那么,另外一个问题,vmalloc可以分配的内存上限是多少呢?参考白金兄的说法,vmalloc分配的内存上限是和cat /proc/meminfo中VmallocTotal的值有关的。我这里的显示结果为:

[root@localhost alloc_large_mem]# cat /proc/meminfo
……
VmallocTotal:   638968 kB
VmallocUsed:      3512 kB
VmallocChunk:   633644 kB

因此,vmalloc最大可分配的内存为600M,由于我的剩余物理内存只有200M左右。所以这里尝试300M的内存观察一下结果。

[root@localhost alloc_large_mem]# free
             total       used       free     shared    buffers     cached
Mem:        385624     101216     284408          0       4348      46800
-/+ buffers/cache:      50068     335556
Swap:       522104      88400     433704
[root@localhost alloc_large_mem]# cat /proc/meminfo | grep Vmalloc
VmallocTotal:   638968 kB
VmallocUsed:      3512 kB
VmallocChunk:   633644 kB
[root@localhost alloc_large_mem]#
[root@localhost alloc_large_mem]# insmod alloc_large_mem.ko memsize=300
[root@localhost alloc_large_mem]# free
             total       used       free     shared    buffers     cached
Mem:        385624     380040       5584          0       1796      21896
-/+ buffers/cache:     356348      29276
Swap:       522104      88400     433704
[root@localhost alloc_large_mem]# cat /proc/meminfo | grep Vmalloc
VmallocTotal:   638968 kB
VmallocUsed:    311032 kB
VmallocChunk:   326440 kB
[root@localhost alloc_large_mem]#

这里测试的情况是虚拟内存的使用情况却是增加了300M左右,而物理内存基本上已经耗尽了。
白金兄曾经测试在启动时 kernel 里 vmalloc=1280M,然后insmod内核模块成功分配到1G的内存。我也曾测试分配500M或400M的情况(虚拟内存上限600多M),但都失败了:

[root@localhost alloc_large_mem]# insmod alloc_large_mem.ko memsize=500
insmod: error inserting 'alloc_large_mem.ko': -1 Cannot allocate memory
[root@localhost alloc_large_mem]# insmod alloc_large_mem.ko memsize=400
insmod: error inserting 'alloc_large_mem.ko': -1 Cannot allocate memory

究其原因,应该是超过了内核启动时默认的vmalloc的值,可以通过指定内核启动时vmalloc=xxx来解决。
以上是用vmalloc申请大块内存的总结。不足之处,请大家多多指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  module 测试