Linux Kernel (Ядро линукса) (часть 1)


Пулы памяти

Пулы памяти являются новым понятием в Linux . В принципе, пул памяти позволяет компоненту ядра (например, подсистеме работы с блочными устройствами) выделить некоторую динамическую память для использования только в таких крайних ситуациях, как нехватка памяти.

Не следует путать пулы памяти с зарезервированными страничными кадрами. Те страничные кадры могут быть использованы только для удовлетворения атомарных запросов на выделение памяти, выдаваемых обработчиками прерываний или кодом критических секций. Что касается пула памяти, он является резервом динамической памяти, который может быть использован только конкретным компонентом ядра, а именно "владельцем” пула. В нормальной ситуации владелец не обращается к резерву. Однако если динамической памяти становится так мало, что все обычные запросы на выделение памяти обречены на провал, компонент ядра может в качестве крайнего средства прибегнуть к помощи специальных функций пула памяти, которые черпают из резерва необходимую память. Таким образом, создание пула памяти аналогично созданию запаса консервов и использованию консервного ножа, когда свежие продукты недоступны.

Нередко пул памяти создается в помощь slab-аллокатору, т. е. используется в качестве резерва объектов для участков памяти. Вообще говоря, пул памяти можно использовать для выделения любых порций динамической памяти, от целых страничных кадров до небольших областей, выделяемых с помощью функции kmaiioc . Поэтому мы в дальнейшем будем называть единицы памяти, с которыми имеет дело пул памяти, элементами памяти.

В поле min nr хранится начальное количество элементов в пуле памяти. Иными словами, значение в этом поле представляет количество элементов, которые владелец пула памяти гарантированно получит от аллокатора памяти. Поле curr nr, которое всегда меньше или равно полю min nr, содержит количество элементов, находящихся в пуле в данный момент. Сами элементы памяти доступны через массив указателей, адрес которого хранится в поле elements.
Методы alloc и free обеспечивают интерфейс с аллокатором памяти, позволяя, соответственно, получать и освобождать элементы памяти. Оба метода могут быть собственными функциями компонента ядра, который владеет пулом памяти.

Когда элементы памяти являются объектами участка, методы alloc и free обычно реализуются функциями mempool_alloc_slab И mempool_f ree_slab , которые просто вызывают функции kmem_cache_alloc() И kmem cache f гее соответственно. В этом случае поле pool data объекта mempooi t содержит адрес дескриптора кэша участков.

Функция mempooi create о создает новый пул памяти. Она принимает в качестве параметров количество элементов min nr, адреса функций, реализующих методы alloc и free, и, возможно, значение поля pooi data. Функция выделяет память под объект mempooi t и массив указателей на элементы памяти, и затем многократно вызывает метод alloc для получения min nr элементов памяти. Функция mempool destroy о, наоборот, освобождает все элементы в пуле, а затем — массив элементов и объект mempooi t.

Чтобы выделить элемент из пула памяти, ядро вызывает функцию mempooi aiiocO, передавая ей адрес объекта mempooi t и флаги выделения памяти. В сущности, функция пытается выделить элемент памяти с помощью аллокатора памяти, вызывая метод alloc в соответствии с флагами, которые она получила в качестве параметров. Если выделение памяти проходит успешно, функция возвращает элемент памяти, не затрагивая пул памяти. В противном случае она берет элемент из пула. Конечно, большое количество операций выделения в условиях дефицита памяти может исчерпать пул. В таком случае, если флаг gfp wait установлен, функция
mempo о 1_а 11 о с блокирует текущий процесс, пока какой-нибудь элемент памяти не будет освобожден для пула памяти.

И наоборот, чтобы освободить элемент для пула памяти, ядро вызывает функцию mempool f гее . ЕСЛИ пул памяти не Заполнен (значение curr_min меньше, чем min nr), функция добавляет этот элемент в пул. В противном случае mempoolf гее вызывает метод free, чтобы освободить элемент для аллокатора памяти.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

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

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...