unsigned long def_flags; /* флаги доступа, используемые
по умолчанию */
unsigned long cpu_vm_mask; /* маска отложенного переключения
буфера TLB */
unsigned long swap_address; /* последний сканированный адрес */
unsigned dumpable:1; /* можно ли создавать файл core? */
int used_hugetlb; /* используются ли гигантские
страницы памяти (hugetlb)? */
mm_context_t context; /* данные, специфичные для аппаратной
платформы */
int core_waiters; /* количество потоков, ожидающих на
создание файла core */
struct completion *core_startup_done; /* условная переменная начала
создания файла core */
struct completion core_done; /* условная переменная завершения
создания файла core */
rwlock_t ioctx_list_lock; /* блокировка списка асинхронного
ввода-вывода (AIO) */
struct kioctx *ioctx_list; /* список асинхронного ввода-вывода (AIO) */
struct kioctx default_kioctx; /* контекст асинхронного ввода-
вывода, используемый по умолчанию */
};
Поле mm_users
— это количество процессов, которые используют данное адресное пространство. Например, если одно и то же адресное пространство совместно используется двумя потоками, то значение поля mm_users
равно двум. Поле mm_count
— это основной счетчик использования структуры mm_struct
. Наличие пользователей структуры, которым соответствует поле mm_users
, приводит к увеличению счетчика mm_count
на единицу. В предыдущем примере значение поля mm_count
равно единице. Когда значение поля mm_users
становится равным нулю (т.е. когда два потока завершатся), только тогда значение поля mm_count
уменьшается на единицу. Когда значение поля mm_count становится равным нулю, то на соответствующую структуру mm_struct
больше нет ссылок, и она освобождается, Поддержка двух счетчиков позволяет ядру отличать главный счетчик использования (mm_count
) от количества процессов, которые используют данную структуру (mm_users
).
Поля mmap
и mm_rb
— это два различных контейнера данных, которые содержат одну и ту же информацию: информацию обо всех областях памяти в соответствующем адресном пространстве. В первом контейнере эта информация хранится в виде связанного списка, а во втором — в виде красно-черного бинарного дерева. Поскольку красно-черное дерево — это разновидность бинарного дерева, то, как и для всех типов бинарного дерева, количество операций поиска заданного элемента в нем равно
Хотя обычно в ядре избегают избыточности, связанной с введением нескольких структур для хранения одних и тех же данных, тем не менее в данном случае эта избыточность очень кстати. Контейнер mmap
— это связанный список, который позволяет очень быстро проходить по всем элементам. С другой стороны, контейнер mm_rb
— это красно-черное дерево, которое очень хорошо подходит для поиска заданного элемента. Области памяти будут рассмотрены в этой главе несколько ниже,
Все структуры mm_struct
объединены в двухсвязный список с помощью нолей mmlist
. Первым элементом этого списка является дескриптор памяти init_mm
, который является дескриптором памяти процесса init. Этот список защищен от конкурентного доступа с помощью блокировки mmlist_lock
, которая определена в файле kernel/fork.с
. Общее количество дескрипторов памяти хранится в глобальной целочисленной переменной mmlist_nr
, которая определена в том же файле.
Выделение дескриптора памяти