Linux Device Drivers 3 / Драйверы устройств Линукс (третье издание): 8.1. The Real Story of kmalloc
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
8.1 Вся правда о kmalloc. VectorVT44Mil 21.03.11 в 19:16 |
|
|
Механизм выделения памяти kmalloc это мощный инструмент, простой и понятный из за сходства с malloc. Выполняется быстро (если не блокируется) и не очищает выделенную память, содержимое остается на месте.[1] Выделенный фрагмент не фрагментирован в физической памяти. В следующих нескольких секциях, мы в деталях опишем работу функции kmalloc, чтобы Вы могли сравнить способы выделения памяти, которые мы обсудим позже. VectorVT44Mil 21.03.11 в 19:31 |
||
|
[1] Среди прочего, это подразумевает, что Вы должны явным образом очистить память, которая может быть использована в юзерспейсе или для записи в устройство; в противном случае, Вы рискуете раскрыть информацию, которая должна оставаться приватной. VectorVT44Mil 21.03.11 в 19:34 |
||
|
8.1.1. Аргумент флаги VectorVT44Mil 21.03.11 в 19:34 |
||
|
Первый аргумент kmalloc это размер выделяемого блока. Второй аргумент, флаги выделения, значительно интереснее, так как контролирует различные стороны поведения kmalloc. VectorVT44Mil 21.03.11 в 19:40 |
||
|
Наиболее часто используемый флаг, GFP_KERNEL, означает, что выделение памяти (внутренне выполняемое через вызов __get_free_pages, являющейся исходником GFP_prefix ) выполняется от имени процесса выполняющегося с приоритетом уровня ядра. Другими словами, это значит что запуск функции приводит к системному вызову от имени процесса. Используя GFP_KERNEL означает, что kmalloc может заставить процесс уснуть в ожидании свободной страницы памяти если вызов произошел в момент ее недостатка. Функция, выделяющая память, используя GFP_KERNEL, должна, тем не менее, быть повторно входимой и не может быть запущена во время атомарной операции. Пока текущий процесс спит, ядро выполняет необходимые операции для выделения свободной памяти, сбрасывая буферы на диск или свопируя память самого процесса. VectorVT44Mil 21.03.11 в 19:57 |
||
|
Не всегда полезно использовать флаг GFP_KERNEL; иногда kmalloc вызывается за пределами контекста процесса. Такой тип вызова может случиться, например, в обработчиках прерываний, тасклетах и таймерах ядра. В этом случае, текущий процесс не уснет, и драйвер должен использовать флаг GFP_ATOMIC вместо этого. На самом деле, ядро старается иметь в запасе несколько страниц памяти чтобы поддерживать атомарные операции выделения памяти. Когда Вы используете GFP_ATOMIC, kmalloc может использовать даже самые последние странички. Однако, если этих последних страниц нет, то выделение закончится неудачей. VectorVT44Mil 22.03.11 в 18:42 |
||
|
Другие флаги можно использовать вместе с GFP_KERNEL и GFP_ATOMIC, или вместо них, хотя эти два удовлетворяют большую часть потребностей драйверов устройств. Все флаги определены в , индивидуальные флаги имеют префикс с двойным подчеркиванием, вроде __GFP_DMA. В добавок, наиболее употребимые комбинации флагов не имеют префикса и их иногда называют"предпочтения выделения". Вот они: VectorVT44Mil 22.03.11 в 18:54 |
||
|
GFP_ATOMIC VectorVT44Mil 22.03.11 в 18:55 |
||
|
GFP_KERNEL VectorVT44Mil 22.03.11 в 18:57 |
||
|
GFP_USER VectorVT44Mil 22.03.11 в 18:58 |
||
|
GFP_HIGHUSER VectorVT44Mil 22.03.11 в 18:59 |
||
|
GFP_NOIO VectorVT44Mil 22.03.11 в 19:05 |
||
|
Флаги, описанные выше, могут дополняться с помощью побитового ИЛИ следующими флагами, которые изменяют алгоритм выделения: VectorVT44Mil 22.03.11 в 19:07 |
||
|
__GFP_DMA VectorVT44Mil 22.03.11 в 19:10 |
||
|
__GFP_HIGHMEM VectorVT44Mil 22.03.11 в 19:12 |
||
|
__GFP_COLD VectorVT44Mil 22.03.11 в 19:18 |
||
|
__GFP_NOWARN VectorVT44Mil 22.03.11 в 19:20 |
||
|
__GFP_HIGH VectorVT44Mil 22.03.11 в 19:25 |
||
|
__GFP_REPEAT VectorVT44Mil 22.03.11 в 19:33 |
||
