2016-04-15 95 views
1

我如何知道在分配之前,我可以创建多大的数组?或者如何定位我的数组,使其与内存映射中的某些内容不冲突?Linux内核模块中的最大指针/数组大小

我有这个配置

VM running on Virtualbox with 
Operating system: Centos 7 
Memory: 2GB 
Processor: [email protected],9Ghz 
Host OS: Suse Leap 41 

而且我有这样的代码:

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 

MODULE_DESCRIPTION("linux module"); 
MODULE_AUTHOR ("doald duck"); 

static int __init KM() { 
    size = 100000; 
    size = 10*100000; 
    printk("creating an int aray of %d 1st ....\n",size); 

    int ia [size]; 
    int ia_ = -1; 
    while (++ia_ < size){ 
     ia [ia_] = ia_ +2000; 
    } 
    return 0; 
} 

static void __exit _KM() { 
    printk ("unloading 'za module "); 
} 

module_init (KM); 
module_exit (_KM); 

如果尺寸保持在100000;该模块加载和rmmod的完美的作品.. 如果不知何故,我做的大小= 10 * 100000然后内核混乱情况,并重新启动

呼叫跟踪功能是:

[ 155.751747] creating an aray of 1000000 1st .... 
[ 155.753448] BUG: unable to handle kernel paging request at ffff88007c408000 
[ 155.753629] IP: [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.753962] PGD 3f32067 PUD 3f35067 PMD 3ed00063 PTE 800000007c408161 
[ 155.754065] Oops: 0003 [#1] SMP 
[ 155.754170] Modules linked in: kernel_module1(POE+) ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter vfat fat snd_intel8x0 snd_ac97_codec ac97_bus snd_seq iTCO_wdt iTCO_vendor_support ppdev snd_seq_device snd_pcm snd_timer snd soundcore parport_pc pcspkr parport lpc_ich mfd_core sg i2c_piix4 video i2c_core ip_tables xfs libcrc32c sr_mod cdrom sd_mod ata_generic crct10dif_generic crc_t10dif crct10dif_common pata_acpi ahci libahci ata_piix serio_raw libata e1000 dm_mirror 
[ 155.754955] dm_region_hash dm_log dm_mod 
[ 155.754979] CPU: 0 PID: 2562 Comm: insmod Tainted: P   OE ------------ 3.10.0-327.13.1.el7.x86_64 #1 
[ 155.755086] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 
[ 155.755190] task: ffff88007c72f300 ti: ffff88007c668000 task.ti: ffff88007c668000 
[ 155.755286] RIP: 0010:[<ffffffffa0037037>] [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.755391] RSP: 0018:ffff88007c29b450 EFLAGS: 00010287 
[ 155.755487] RAX: 000000000005b2ec RBX: ffffffff81951020 RCX: ffff88007c29b450 
[ 155.755594] RDX: 000000000005babc RSI: 0000000078e678e4 RDI: 0000000000000246 
[ 155.755687] RBP: ffff88007c66bd58 R08: 0000000000000086 R09: 0000000000000269 
[ 155.755782] R10: 0000000000000000 R11: ffff88007c66ba6e R12: ffff8800026609c0 
[ 155.755877] R13: ffffffffa0037000 R14: 0000000000000000 R15: ffffffffa03e4000 
[ 155.755974] FS: 00007f6dfdbc4740(0000) GS:ffff88007da00000(0000) knlGS:0000000000000000 
[ 155.756074] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b 
[ 155.756164] CR2: ffff88007c408000 CR3: 000000007c606000 CR4: 00000000000006f0 
[ 155.756262] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 
[ 155.756356] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 
[ 155.756451] Stack: 
[ 155.756527] 000007d1000007d0 000007d3000007d2 000007d5000007d4 000007d7000007d6 
[ 155.756635] 000007d9000007d8 000007db000007da 000007dd000007dc 000007df000007de 
[ 155.756745] 000007e1000007e0 000007e3000007e2 000007e5000007e4 000007e7000007e6 
[ 155.756842] Call Trace: 
[ 155.756923] Code: e5 e8 23 81 5f e1 be 40 42 0f 00 48 c7 c7 48 30 3e a0 31 c0 e8 10 81 5f e1 48 81 ec 08 09 3d 00 31 c0 48 89 e1 8d 90 d0 07 00 00 <89> 14 81 48 ff c0 48 3d 40 42 0f 00 75 ec 48 c7 c7 3b 30 3e a0 
[ 155.757153] RIP [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.757246] RSP <ffff88007c29b450> 
[ 155.757329] CR2: ffff88007c408000 

主要的原因是因为它达到一个地址不能被分配...

+5

大多数情况下,**不会在内核**的堆栈中分配任何内容。 –

+1

在内核中做kmalloc。如果由于某种原因失败,它不会惊慌。 – stark

+0

是的,kmalloc是去这里的方法 – Luanf

回答

4

在内核空间中运行的进程的默认堆栈大小为8192字节,但根据体系结构可能会更少。

要询问相当大的记忆,请使用kmalloc和它的朋友。

size_t sz = 10000; 
int *ia = kmalloc(sz, GFP_KERNEL); 
if (ia == NULL) 
{ 
    /* allocation failed, handle error */ 
    return -1; 
} 
/* OK, though it may have allocated more than you asked for */ 
+0

优秀, 我在大数字之前尝试过kmalloc,这是检查NULL的最佳解决方案:) –