Функция | Описание |
---|---|
alloc_page(gfp_mask) | Выделяет одну страницу памяти и возвращает указатель на соответствующую ей структуру page |
alloc_pages(gfp_mask, order) | Выделяет 2order страниц памяти и возвращает указатель на структуру page первой страницы |
__get_free_page(gfp_mask) | Выделяет одну страницу памяти и возвращает указатель на ее логический адрес |
__get_free_pages(gfp_mask, order) | Выделяет 2order страниц памяти и возвращает указатель на логический адрес первой страницы |
get_zeroed_page(gfp_mask) | Выделяет одну страницу памяти, обнуляет ее содержимое и возвращает указатель на ее логический адрес |
Освобождение страниц
Для освобождения страниц, которые больше не нужны, можно использовать следующие функции.
void __free_pages(struct page *page, unsigned int order);
void free_pages(unsigned long addr, unsigned int order);
void free_page(unsigned long addr);
Необходимо быть внимательными и освобождать только те страницы памяти, которые вам выделены. Передача неправильного значения параметра page
, addr
или order
может привести к порче данных. Следует помнить, что ядро доверяет себе. В отличие от пространства пользователя, ядро с удовольствием зависнет, если вы попросите. Рассмотрим пример. Мы хотим выделить 8 страниц памяти.
page = __get_free_pages(GFP_KERNEL, 3);
if (!page) {
/* недостаточно памяти: эту ошибку необходимо обработать самим! */
return -ENOMEM;
}
/* переменная 'page' теперь содержит адрес
первой из восьми страниц памяти */
free_pages(page, 3);
/*
* наши страницы памяти теперь освобождены и нам больше нельзя
* обращаться по адресу, который хранится в переменной 'page'
*/
Значение GFP_KERNEL
, которое передается в качестве параметра, — это пример флага gfp_mask
, который скоро будет рассмотрен детально.
Обратите внимание на проверку ошибок после вызова функции __get_free_pages()
. Выделение памяти в ядре
Низкоуровневые функции выделения памяти полезны, когда необходимы участки памяти, которые находятся в смежных физических страницах, особенно если необходима одна страница или очень большое количество страниц. Для более общего случая, когда необходимо выделить заданное количество байтов памяти, ядро предоставляет функцию kmalloc()
.
Функция kmalloc()
Функция kmalloc()
работает аналогично функции malloc()
пространства пользователя, за исключением того, что добавляется еще один параметр flags
. Функция kmalloc()
— это простой интерфейс для выделения в ядре участков памяти размером в заданное количество байтов. Если необходимы смежные страницы физической памяти, особенно когда их количество близко целой степени двойки, то ранее рассмотренные интерфейсы могут оказаться лучшим выбором. Однако для большинства операций выделения памяти в ядре функция kmalloc()
— наиболее предпочтительный интерфейс.
Рассматриваемая функция определена в файле
следующим образом.
void * kmalloc(size_t size, int flags);
Данная функция возвращает указатель на участок памяти, который имеет размер size
байт[63]. Выделенный участок памяти содержит физически смежные страницы. В случае ошибки функция возвращает значение NULL
. Выделение памяти в ядре заканчивается успешно, только если доступно достаточное количество памяти. Поэтому после вызова функции kmalloc()
всегда необходимо проверять возвращаемое значение на равенство значению NULL
и соответственным образом обрабатывать ошибку.