Рассмотрим пример. Допустим, нам необходимо выделить достаточно памяти для того, чтобы в ней можно было разместить некоторую воображаемую структуру dog
.
struct dog *ptr;
ptr = kmalloc(sizeof (struct dog), GFP_KERNEL);
if (!ptr)
/* здесь обработать ошибку ... */
Если вызов функции kmalloc()
завершится успешно, то переменная ptr
будет указывать на область памяти, размер которой больше указанного значения или равен ему. Флаг GFP_KERNEL
определяет тип поведения системы выделения памяти, когда она пытается выделить необходимую память при вызове функции kmalloc()
.
Флаги gfp_mask
Выше были показаны различные примеры использования флагов, которые модифицируют работу системы выделения памяти, как при вызове низкоуровневых функций, работающих на уровне страниц, так и при использовании функции kmalloc()
. Теперь давайте рассмотрим их более детально.
Флаги разбиты на три категории: модификаторы операций, модификаторы зон и флаги типов. Модификаторы операций указывают, GFP_KERNEL
— это флаг типа, который используется кодом, выполняющимся в ядре в контексте процесса. Рассмотрим все флаги отдельно.
Все флаги, включая модификаторы операций, определены в заголовочном файле
. Подключение файла
также подключает и этот заголовочный файл, поэтому его не часто приходится подключать явно. На практике обычно лучше использовать флаги типов, которые будут рассмотрены дальше. Тем не менее полезно иметь представление об индивидуальных флагах. В табл. 11.3 показан список модификаторов операций.
Таблица 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) |
Описанные модификаторы можно указывать вместе, как показано в следующем примере.
ptr = kmalloc(size, __GFP_WAIT | __GFP_IO | __GFP_FS);