2016-10-09 1 views
0

Я читаю исходный код драйвера устройства.kmalloc many struct, должен ли я 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

Это настоящий исходный код от драйвера рабочего устройства? Блокировка выполняется на 'lock', однако разблокировка выполняется на другой переменной' spinlock_t' 'sq-> avmi_lock'. Это не выглядит правильным. – Aleksey

+0

'было бы лучше ...' - Это сильно зависит от ваших потребностей. Фактически вы выбираете * тип контейнера * для сообщений: ** список ** (выделение на элемент, каждый элемент должен содержать привязку к следующему) или ** массив **/** вектор ** (один распределение для всех элементов, к любому элементу можно получить доступ по целочисленному индексу). – Tsyvarev

ответ

1

Трудно сказать что-либо окончательное, не видя исходного кода. Обоснование для выделения памяти таким образом может сильно отличаться от всего, что мы придумали здесь.

Одно разумное обоснование может быть этим. Как вы можете видеть, выделенные элементы связаны друг с другом в отдельном списке. Это может быть только начальный пул элементов, который может быть расширен или сокращен по мере запуска драйвера. Некоторые элементы из исходного пула могут быть удалены и освобождены позднее. Если вы выделили эту память в одном распределении, вы не сможете этого сделать. В связи с тем, что элементы связаны в связанном списке, я не думаю, что это будет использоваться как массив, как предлагает Tsyvarev.

Я должен сказать, что чаще всего рассуждение может быть охарактеризовано одним словом: потому что. Потому что автор кода решил, что делать это таким образом было более удобно, или яснее, и т. Д. И т. Д. К сожалению, это происходит все время. Пока эти места не критичны (т. Е. Не в горячем пути), все в порядке. Вы не можете все исправить.

РЕДАКТИРОВАТЬ
Как отмечалось в приведенной ниже реакции, выделение для до 16 пунктов. Это может быть преднамеренное дизайнерское решение. Если в какой-то момент происходит сбой распределения, он просто вырывается из цикла выделения, выделяя столько элементов, сколько может из 16. Это на самом деле соответствует идее, что эти элементы могут составлять начальный пул до 16 элементов.

+0

* «Потому что» * также называется «выбор дизайна». – sawdust

+0

Несомненно. Просто эти варианты дизайна редко комментируются в коде. – Aleksey

0

Этот код пытается выделить до до 16 struct foo s. Но если памяти недостаточно, тогда она все равно будет выделять некоторые. Ваше предлагаемое изменение состоит в попытке выделить 16 struct foo и сбой, если вы не можете этого сделать. Что делать, если есть только место для некоторых распределений?

Кроме того, с одним распределением распределитель должен найти непрерывную область памяти, тогда как с несколькими он может иметь дело с фрагментированной памятью.

Смежные вопросы