1

How do I know before allocating, how big of an array can I create? Or how to position my array so it does not conflict with something in the memory map?

I have this configuration

VM running on Virtualbox with
Operating system: Centos 7
Memory: 2GB
Processor: E7500@2,9Ghz
Host OS: Suse Leap 41 

And I have this code:

#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);

if size stays at 100000 ; the module is loading and rmmod works perfectly .. if somehow I do size = 10*100000 then kernel panic happens and reboot

call trace is :

[  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

mostly the reason is because it reaches an address that cannot be assigned ...

4
  • 5
    Mostly, do not allocate anything on stack in the kernel. Commented Apr 15, 2016 at 13:21
  • 1
    In the kernel do kmalloc. It won't panic if it fails for some reason. Commented Apr 15, 2016 at 13:21
  • Yep, kmalloc is the way to go here Commented Apr 15, 2016 at 13:33
  • Don't allocate the maximum you can get, but the minimum you need. This is a kernel, it's purpose is to provide resources to the applications, not use them itself. Commented Apr 15, 2016 at 13:37

1 Answer 1

5

The default stack size for a process running in kernel space is 8192 bytes, though it may be less depending on architecture.

To ask for memory of significant size, use kmalloc and it's friends.

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 */
Sign up to request clarification or add additional context in comments.

1 Comment

excellent , I tried a kmalloc before on big numbers , and this is the best solution to check for NULL :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.