it-swarm.com.ru

В чем разница между vmalloc и kmalloc?

Я погуглил и обнаружил, что большинство людей выступает за использование kmalloc, поскольку вы гарантированно получите смежные физические блоки памяти. Однако, также кажется, что kmalloc может потерпеть неудачу, если не может быть найден непрерывный блок физический, который вы хотите.
Каковы преимущества наличия непрерывного блока памяти? В частности, зачем мне иметь непрерывный физический блок памяти в системном вызове ? Есть ли причина, по которой я не мог просто использовать vmalloc?
Наконец, если бы я должен был выделить память во время обработки системного вызова, я должен указать GFP_ATOMIC? Системный вызов выполняется в атомарном контексте?

GFP_ATOMIC
Распределение является приоритетным и не спит. Этот флаг используется в обработчиках прерываний, нижних половинах и других ситуациях, когда вы не можете спать.

GFP_KERNEL Это нормальное распределение и может блокироваться. Этот флаг используется в коде контекста процесса, когда он безопасен для сна.

104
FreeMemory

Вам следует беспокоиться об использовании физически непрерывной памяти, если к буферу будет обращаться устройство DMA по физически адресуемой шине (например, PCI). Проблема в том, что многие системные вызовы не имеют возможности узнать, будет ли их буфер в конечном итоге передан устройству DMA: как только вы передадите буфер в другую подсистему ядра, вы действительно не сможете знать, куда он пойдет. , Даже если ядро ​​не использует буфер для DMA сегодня, будущее развитие может сделать это.

vmalloc часто медленнее, чем kmalloc, поскольку может потребоваться переназначить пространство буфера в практически непрерывный диапазон. kmalloc никогда не перераспределяется, хотя, если не вызывается с GFP_ATOMIC, kmalloc может блокироваться.

размер kmalloc ограничен буфером, который он может предоставить: 128 КБ*), Если вам нужен действительно большой буфер, вы должны использовать vmalloc или какой-то другой механизм, такой как резервирование высокой памяти при загрузке.

*)  Это было верно для более ранних ядер. В последних ядрах (я проверял это на 2.6.33.2) максимальный размер одного kmalloc составляет до 4 МБ! (Я написал довольно подробный пост об этом .) - kaiwan

Для системного вызова вам не нужно передавать GFP_ATOMIC в kmalloc (), вы можете использовать GFP_KERNEL. Вы не обработчик прерываний: код приложения входит в контекст ядра посредством ловушки, это не прерывание.

85
DGentry

Краткий ответ: скачайте Драйверы устройств Linux и прочитайте главу об управлении памятью.

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

vmalloc () используется очень редко, потому что ядро ​​редко использует виртуальную память. kmalloc () - это то, что обычно используется, но вы должны знать, каковы последствия различных флагов, и вам нужна стратегия, чтобы справиться с тем, что происходит, когда он терпит неудачу - особенно если вы находитесь в обработчике прерываний, как вы и предлагали.

16
Mike Heinz

Разработка ядра Linux Робертом Лавом (глава 12, стр. 244 в 3-м издании) очень четко отвечает на это.

Да, физически непрерывная память не требуется во многих случаях. Основной причиной использования kmalloc в ядре больше, чем vmalloc, является производительность. В книге объясняется, что когда большие фрагменты памяти выделяются с помощью vmalloc, ядро ​​должно отображать физически несмежные фрагменты (страницы) в одну непрерывную область виртуальной памяти. Поскольку память является практически непрерывной и физически несмежной, в таблицу страниц необходимо добавить несколько сопоставлений виртуальных и физических адресов. И в худшем случае будет (размер буфера/размер страницы) количество отображений, добавленных в таблицу страниц.

Это также добавляет нагрузку на TLB (записи кэша, хранящие недавние сопоставления виртуальных и физических адресов) при доступе к этому буферу. Это может привести к избиению .

12
codetwiddler

Функции kmalloc() & vmalloc() представляют собой простой интерфейс для получения памяти ядра в кусках размером в байты.

  1. Функция kmalloc() гарантирует, что страницы являются физически смежными (и практически смежными).

  2. Функция vmalloc() работает аналогично функции kmalloc(), за исключением того, что она выделяет память, которая является только виртуально смежной и необязательно физически смежной.

10
Yogeesh H T

Каковы преимущества наличия непрерывного блока памяти? В частности, зачем мне иметь непрерывный физический блок памяти в системном вызове? Есть ли причина, по которой я не мог просто использовать vmalloc?

Из Google "Мне повезет" на vmalloc:

kmalloc является предпочтительным способом, если вам не нужны очень большие области. Проблема в том, что если вы хотите выполнить DMA с/на какое-либо аппаратное устройство, вам необходимо используйте kmalloc, и вам, вероятно, понадобится больший кусок. Решение состоит в том, чтобы выделить память как можно скорее, прежде чем память будет фрагментирована.

5
Dark Shikari

В 32-битной системе kmalloc () возвращает логический адрес ядра (хотя это и виртуальный адрес), который имеет прямое отображение (фактически с постоянным смещением) на физический адрес. Это прямое сопоставление гарантирует, что мы получим непрерывный физический кусок оперативной памяти. Подходит для DMA, где мы даем только начальный указатель и после этого ожидаем непрерывное физическое отображение для нашей операции.

vmalloc () возвращает виртуальный адрес ядра, который, в свою очередь, может не иметь непрерывного отображения в физической памяти. Полезно для выделения большого объема памяти и в тех случаях, когда мы не заботимся о том, чтобы память, выделенная для нашего процесса, была непрерывной и в физической памяти.

2
a.saurabh

Одним из других отличий является то, что kmalloc будет возвращать логический адрес (иначе вы указываете GPF_HIGHMEM). Логические адреса размещаются в "малой памяти" (в первом гигабайте физической памяти) и сопоставляются непосредственно с физическими адресами (используйте макрос __pa для его преобразования). Это свойство подразумевает, что kmalloced memory является непрерывной памятью.

С другой стороны, Vmalloc может возвращать виртуальные адреса из "большой памяти". Эти адреса не могут быть преобразованы в физические адреса прямым способом (вы должны использовать функцию virt_to_page).

1
Jezz