Разработка ядра Linux
Шрифт:
Значение
Обратите внимание на проверку ошибок после вызова функции
Низкоуровневые функции выделения памяти полезны, когда
Функция
Функция
Рассматриваемая функция определена в файле
Данная функция возвращает указатель на участок памяти, который имеет размер хотя бы
63
Данная функция может выделить памяти больше, чем указано, и нет никакой возможности узнать, на сколько больше! Поскольку в своей основе система выделения памяти в ядре базируется на страницах, некоторые запросы на выделение памяти могут округляться, чтобы хорошо вписываться е области доступной памяти. Ядро никогда не выделит меньше памяти, чем необходимо. Если ядро не в состоянии найти хотя бы указанное количество байтов, то операция завершится неудачно и функции возвратит значение
Рассмотрим пример. Допустим, нам необходимо выделить достаточно памяти для того, чтобы в ней можно было разместить некоторую воображаемую структуру
Если вызов функции
Флаги
Выше были показаны различные примеры использования флагов, которые модифицируют работу системы выделения памяти, как при вызове низкоуровневых функций, работающих на уровне страниц, так и при использовании функции
Флаги разбиты на три категории: модификаторы операций, модификаторы зон и флаги типов. Модификаторы операций указывают, каким образом ядро должно выделять указанную память. В некоторых ситуациях только некоторые методы могут использоваться для выделения памяти. Например, обработчики прерываний могут потребовать от ядра, что нельзя переходить в состояние ожидания при выделении памяти (поскольку обработчики прерывания не могут быть перепланированы), Модификаторы зоны указывают, откуда нужно выделять память. Как было рассказано, ядро делит физическую память на несколько зон, каждая из которых служит для различных целей. Модификаторы зоны указывают, из какой зоны выделять память. Флаги типов представляют собой различные комбинации модификаторов операций и зон, которые необходимы для определенного типа
Все флаги, включая модификаторы операций, определены в заголовочном файле
Таблица 11.3. Модификаторы операций
Флаг | Описание |
---|---|
__GFP_WAIT | Операция выделения памяти может переводить текущий процесс в состояние ожидания |
__GFP_HIGH | Операция выделения памяти может обращаться к аварийным запасам |
__GFP_IO | Операция выделения памяти может использовать дисковые операции ввода-вывода |
__GFP_FS | Операция выделения памяти может использовать операции ввода- вывода файловой системы |
__GFP_COLD | Операция выделения памяти должна использовать страницы памяти, содержимое которых не находится в кэше процессора (cache cold) |
__GFP_NOWARN | Операция выделения памяти не будет печатать сообщения об ошибках |
__GFP_REPEAT | Операция выделения памяти повторит попытку выделения в случае ошибки |
__GFP_NOFAIL | Операция выделения памяти будет повторять попытки выделения неопределенное количество раз |
__GFP_NORETRY | Операция выделения памяти никогда не будет повторять попытку выделения памяти |
__GFP_NO_GROW | Используется внутри слябового распределителя памяти (slab layer) |
__GFP_COMP | Добавить метаданные составной (compound) страницы памяти. Используется кодом поддержки больших страниц памяти (hugetlb) |
Описанные модификаторы можно указывать вместе, как показано в следующем примере.
Этот код дает инструкцию ядру (а именно функции
Большинство запросов на выделение памяти указывают эти модификаторы, но это делается косвенным образом с помощью флагов типа, которые скоро будут рассмотрены. Не нужно волноваться, у вас не будет необходимости каждый раз разбираться, какие из этих ужасных флагов использовать при выделении памяти!
Модификаторы зоны указывают, из какой зоны должна выделяться память. Обычно выделение может происходить из любой зоны. Однако ядро предпочитает зону
Существует всего два модификатора зоны, поскольку, кроме зоны
Таблица 11.4. Модификаторы зоны
Флаг | Описание |
---|---|
__GFP_DMA | Выделять память только из зоны ZONE_DMA |
__GFP_HIGHMEM | Выделять память только из зон ZONE_HIGHMEM и ZONE_NORMAL |