我已经google了一下,发现大多数人都主张使用kmalloc
,因为你可以保证获得连续的物理内存块.但是,kmalloc
如果找不到您想要的连续物理块,它似乎也会失败.
拥有一块连续的内存块有什么好处?具体来说,为什么我需要在系统调用中拥有连续的物理内存块?我有什么理由不能使用吗?
最后,如果我在处理系统调用期间分配内存,我应该指定吗?系统调用是在原子上下文中执行的吗?vmalloc
GFP_ATOMIC
GFP_ATOMIC
分配是高优先级的,不会睡眠.这是在中断处理程序,下半部分和其他无法睡眠的情况下使用的标志.
GFP_KERNEL
这是正常分配,可能会阻止.这是在安全睡眠时在进程上下文代码中使用的标志.
我有一个加载内核模块的问题,有一个大的数据结构,大约2Gb的内存大小 - 我是否预先分配表(以便它在我执行时显示在.bss中size -A module.ko
或vmalloc()
在加载时尝试它,模块加载失败insmod: error inserting 'module.ko': -1 Cannot allocate memory
.
我试着调试上的用户模式Linux上的问题,但我得到了一堆段错误的(可以继续在gdb,但有一个控制台消息结束了overflow in relocation type 10 val <value in the ball park of 6G>
和'module' likely not compiled with -mcmodel=kernel
我认为与Kbuild
该-mcmodel
应是正确的,对不对?
所以问题是:
-mcmodel=large
内核模块并期望它工作吗?我已经尝试过debian squeeze,64位,2.6.32-5-amd64(主机),8Gb内存和2.6.32 in uml 4G内存,所以这不应该是普通的内存不足问题.
如果存在这样的限制,可以获得超出限制的额外功劳:)
我有一个非常大的驱动程序模块,我正在尝试编译最近的Linux内核(3.4.4).我可以insmod
使用2.6.27.25内核成功编译和使用相同的模块.GCC版本也不同,4.7.0对4.3.0.请注意,此模块非常复杂,我不能简单地浏览所有代码和所有makefile.
当"插入"模块时,我得到一个Cannot allocate memory
带有以下痕迹:
vmap allocation for size 30248960 failed: use vmalloc=<size> to increase size.
vmalloc: allocation failure: 30243566 bytes
insmod: page allocation failure: order:0, mode:0xd2
Pid: 5840, comm: insmod Tainted: G O 3.4.4-5.fc17.i686 #1
Call Trace:
[<c092702a>] ? printk+0x2d/0x2f
[<c04eff8d>] warn_alloc_failed+0xad/0xf0
[<c05178d9>] __vmalloc_node_range+0x169/0x1d0
[<c0517994>] __vmalloc_node+0x54/0x60
[<c0490825>] ? sys_init_module+0x65/0x1d80
[<c0517a60>] vmalloc+0x30/0x40
[<c0490825>] ? sys_init_module+0x65/0x1d80
[<c0490825>] sys_init_module+0x65/0x1d80
[<c050cda6>] ? handle_mm_fault+0xf6/0x1d0
[<c0932b30>] ? spurious_fault+0xae/0xae
[<c0932ce7>] ? do_page_fault+0x1b7/0x450
[<c093665f>] sysenter_do_call+0x12/0x28
-- clip --
Run Code Online (Sandbox Code Playgroud)
显而易见的答案似乎是模块分配了太多内存,但是:
因此,我怀疑新内核的问题与有限的内存没有直接关系.
新内核抱怨 …
我有一个基于arm64的dragonboard410c,当它启动时,它会显示内存布局:
software IO TLB [mem 0xb6c00000-0xbac00000] (64MB) mapped at [ff]
Memory: 780212K/951296K available (9940K kernel code, 1294K rwda)
Virtual kernel memory layout:
vmalloc : 0xffffff8000000000 - 0xffffffbdbfff0000 ( 246 )
vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 )
0xffffffbdc0000000 - 0xffffffbdc1000000 ( 16 )
fixed : 0xffffffbffa7fd000 - 0xffffffbffac00000 ( 4108 )
PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000 ( 16 )
modules : 0xffffffbffc000000 - 0xffffffc000000000 ( 64 )
memory : 0xffffffc000000000 - 0xffffffc040000000 ( 1024 )
.init : 0xffffffc000e49000 …
Run Code Online (Sandbox Code Playgroud) 在32位x86平台上,如果vmalloc()可以从ZONE_NORMAL或ZONE_HIGHMEM分配内存,是否意味着即使我放大ZONE_HIGHMEM,vmalloc()可以使用的实际总范围也不变?我做了一个扩大ZONE_HIGHMEM的测试,vmalloc()的一次性分配可能比以前大得多.那么这是否意味着vmalloc()实际上只从ZONE_HIGHMEM分配内存?