2016-10-09 29 views
0

我正在閱讀設備驅動程序的源代碼。kmalloc許多結構,我應該一次kmalloc全部或分別

它試圖用kmalloc 16 struct foo

spin_lock_bh(&sq->lock); 
for (i=0; i<16; i++) { 
     msg = kmalloc(sizeof(*msg), GFP_ATOMIC); 
     if (!msg) 
       break; 
     msg->next = sq->msg_first; 
     sq->msg_first = msg; 
     sq->nr_msgs++; 
}  
spin_unlock_bh(&sq->lock); 

所以,這將是更好kmalloc(sizeof(*msg) * 16, GFP_ATOMIC)?爲什麼?

+0

這是來自工作設備驅動程序的真實源代碼嗎?在鎖上執行鎖定,然後在不同的'spinlock_t'變量'sq-> avmi_lock'上解鎖。這看起來不正確。 – Aleksey

+0

'會更好嗎......' - 這是非常依賴你的需求。實際上,你正在爲消息選擇一個*類型的容器*:** list **(爲每個元素分配,每個元素需要包含到下一個元素的鏈接)或** array **/** vector **(single分配給所有元素,任何元素都可以通過整數索引來訪問)。 – Tsyvarev

回答

1

在沒有看到源代碼的情況下很難說任何明確的。以這種方式進行內存分配的基本原理可能與我們在此討論的任何內容有很大不同。

一個合理的基本原理可能是這樣的。正如你所看到的,分配的項目在一個單獨的鏈接列表中鏈接在一起。這可能只是一個初始物品池,可以在驅動程序運行時擴展或縮短。初始池中的某些項目可能會在稍後時間被移除和釋放。如果你要在一次分配中分配這個內存,你將無法做到這一點。由於這些項目鏈接到鏈接列表中,我不認爲這將作爲Tsyvarev暗示的陣列使用。

我必須說,多數情況下理由可以用一個單詞來表徵:因爲。因爲代碼的作者認爲這樣做更方便,或更清晰等等。不幸的是,這種情況一直髮生。只要這些地方不重要(即不在熱門路線),沒關係。你無法解決所有問題。

EDIT
如下面的響應所指出的,分配是用於高達 16項。這可能是一個故意的設計決定。如果分配在某個時候失敗了,它就會分配循環分配儘可能多的項目,因爲它可能超過16個。這實際上適合於這些項目可能構成初始池直至 16個項目的想法。

+0

*「因爲」*也被稱爲「設計選擇」。 – sawdust

+0

當然。只是這些設計選擇很少在代碼中評論。 – Aleksey

0

此代碼嘗試分配向上至16 struct foo s。但是如果沒有足夠的內存,那麼它仍然會分配一些內存。您建議的更改是嘗試分配16 struct foo,如果不能這樣做,則嘗試失敗。如果只有一些分配的空間會怎麼樣?

此外,一個分配的分配器必須找到一個連續的內存區域,而多個它可以處理碎片內存。

相關問題