2017-05-30 109 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的數據。 該計算在sbd_init()的原因是:

Device.size = nsectors * logical_block_size; 

Device.size是unsigned long而模塊參數nsectorslogical_block_size是整數。

現在,當你locgical_block_size設置爲1024和nsectors到2097152(其中總計到2GB的空間),計算完成的有符號整數,因此結果是:

1024 * 2097152 = -2147483648 

當這是隱含地轉換爲unsigned long(通過分配給Device.size),結果爲18446744071562067968,然後傳遞給vmalloc()(可能)稍微超過物理內存和vmalloc保留區域,這是Linux x86_64上的32TB。

的解決方案是執行計算作爲unsigned long

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

那麼它應該工作正常。

0

在舊版本的Linux內核中,vmalloc()可以分配的內存限制爲64 MB,但在版本3.10.*中理論上應該受物理內存的限制。

+1

這應該是一個評論,因爲它並沒有真正幫助解決OPs問題 – Ctx

+0

@Ctx:這**在一個提問者的問題上回答** * - 是否對內存大小有限制?可以通過vmalloc分配嗎?'所以可以是*答案*。 – Tsyvarev