2017-05-30 10 views
3

vmalloc()を使用して、大きなメモリをカーネルモジュールに割り当てようとしています。 64GBのRAMを搭載した64ビットLinux(3.10.0-514.2.2.el7.x86_64)に2GB以上のメモリを割り当てることができません。vmallocを使用して大量のメモリをカーネルモジュールに割り当てる

これらは、関連するコード部分である:

... 

static int logical_block_size = 512; 
module_param(logical_block_size, int, 0); 
static int nsectors = 1024; /* How big the drive is */ 
module_param(nsectors, int, 0); 

... 

/* 
* The internal representation of our device. 
*/ 
static struct sbd_device { 
    unsigned long size; 
    spinlock_t lock; 
    u8 *data; 
    struct gendisk *gd; 
} Device; 

... 

static int __init sbd_init(void) { 
    /* 
    * Set up our internal device. 
    */ 
    Device.size = nsectors * logical_block_size; 
    spin_lock_init(&Device.lock); 
    Device.data = vmalloc(Device.size); 
    ... 

vmalloc介して割り当て可能なメモリのサイズに制限がありますか?大量のメモリをカーネルモジュールに割り当てる別の方法はありますか?

+0

理論上は、限界は32TBか、物理的に利用可能なRAMでなければなりません。)割り当てようとしているときにカーネルからメッセージを受け取りますか? – Ctx

+0

'vmalloc()'をどのように使っているか教えてください。 – syntagma

+2

2GiB RAMをカーネルモジュールに割り当てることは非常に悪い考えです。 XY問題のように見えます。 – Olaf

答えて

0

お客様の質問にお答えするには、コメントにはSimple Block Driverのコードを参照してください。

理由は、16 Exabytesのデータを割り当てようとしているためです。モジュールはnsectorslogical_block_sizeは整数であるパラメータながら

Device.size = nsectors * logical_block_size; 

Device.sizeがunsigned longです:sbd_init()で この計算は理由です。もし1024にlocgical_block_size設定しnsectors(空間2GBのに合計)2097152に、計算は、このように結果は、符号付き整数として行われる今

1024 * 2097152 = -2147483648 

これは暗黙のうちにunsigned long(Device.sizeへの割り当てによって)にキャストされた場合、結果はvmalloc()(おそらく)物理メモリとvmalloc予約領域をわずかに超え、Linux x86_64上の32TBに渡される18446744071562067968になります。

ソリューションはunsigned longとして計算を実行することです:

Device.size = (unsigned long) nsectors * logical_block_size; 

予想通りその後、それが動作するはずです。

0

Linuxカーネルの古いバージョンでは、vmalloc()が割り当てることができるメモリには64 MBの制限がありましたが、バージョン3.10.*では理論上は物理メモリによって制限されるはずです。

+1

OPの問題を解決するのに本当に役に立たないので、これはコメントでなければなりません。 – Ctx

+0

@Ctx:この**は質問者の質問に答えます。* - 'メモリのサイズに制限はありますか? vmallocを介して割り当てることができますか? 'これは*回答*になります。 – Tsyvarev

関連する問題