Буферы быстрого преобразования адреса (TLB) в Linux

Помимо аппаратных кэшей общего назначения у процессоров 80×86 есть еще один кэш, называемый буфером быстрого преобразования адреса (Translation Lookaside Buffer, TLB) и предназначенный для ускорения преобразования линейных адресов. Когда линейный адрес используется впервые, соответствующий физический адрес вычисляется с использованием медленных операций обращения к Таблицам Страниц в оперативной памяти. Затем физический адрес сохраняется в записи TLB-буфера, чтобы последующие ссылки на тот же линейный адрес разрешались быстрее.
В многопроцессорных системах каждый процессор имеет собственный TLB-буфер, называемый локальным. В отличие от аппаратного кэша, записи в TLB-буферах не нуждаются в синхронизации, потому что процессы, работающие на разных процессорах, могут ассоциировать один линейный адрес с разными физическими адресами.
Когда изменяется содержимое управляющего регистра у какого-то процессора, аппаратная часть автоматически делает недействительными все записи в локальном TLB-буфере, потому что используется новый набор таблиц страниц, а TLB-буферы указывают на устаревшие данные.
Управление страницами в Linux
В Linux принята универсальная модель управления страницами, которая подходит как к 32-разрядным, так и к 64-разрядным архитектурам. Для 32-разрядных архитектур достаточно двух уровней управления страницами, а 64-разрядные требуют большего количества уровней. Вплоть до версии 2.6.10, модель управления страницами в Linux состояла из трех уровней.
Начиная с версии, была принята четырехуровневая модель. Соответствующие четыре типа таблиц страниц и называются так:
глобальный каталог страниц;
верхний каталог страниц;
средний каталог страниц;
Таблица Страниц.
Глобальный каталог страниц включает в себя адреса нескольких верхних каталогов страниц, которые, в свою очередь, содержат адреса нескольких средних каталогов страниц, а те — адреса нескольких Таблиц Страниц. Каждая запись Таблицы Страниц указывает на страничный кадр. Таким образом, линейный адрес можно разбить на пять частей. Для 32-разрядных архитектур без расширения физических адресов достаточно двух уровней управления страницами. Linux фактически исключает из модели поля верхнего и среднего каталогов страниц, считая, что эти поля содержат нулевые биты. Тем не менее позиции верхнего и среднего каталогов страниц в цепочке указателей сохраняются, чтобы один и тот же код работал как на 32-разрядной, так и на 64-разрядной архитектуре. Ядро сохраняет позиции верхнего каталога страниц и среднего каталога страниц, устанавливая количество записей в них 1 и отображая эти записи в соответствующую запись глобального каталога страниц.
В 32-разрядных архитектурах при включенном механизме расширения физических адресов применяется трехуровневое управление страницами. Глобальный каталог страниц в Linux соответствует таблице указателей на каталог страниц в модели управления страницами 80×86, верхний каталог страниц отсутствует, средний каталог страниц соответствует каталогу страниц, а Таблица Страниц Linux соответствует Таблице Страниц 80×86.
Наконец, в 64-разрядных архитектурах используются три или четыре уровня управления страницами, в зависимости от того, как аппаратная часть разбивает линейный адрес.
Работа операционной системы Linux с процессами сильно зависит от подхода к управлению страницами. Например, автоматическое преобразование линейных адресов в физические позволяет решать следующие задачи:
— присваивать разные пространства физических адресов разным процессам, что послужит эффективной защитой от ошибок адресации;
— проводить различие между страницами (блоками данных) и страничными кадрами (физическими адресами в основной памяти). Это позволяет записать на диск страницу, хранящуюся в одном страничном кадре, а потом загрузить ее в другой страничный кадр. Подобный подход лежит в основе механизма виртуальной памяти.
Каждый процесс имеет собственный глобальный каталог страниц и собственный набор Таблиц Страниц. Когда происходит переключение процессов, Linux сохраняет содержимое управляющего регистра в дескрипторе выполнявшегося процесса, а затем загружает в регистр сгз значение, хранящееся в дескрипторе процесса, который будет выполняться далее. Таким образом, когда процесс возобновит свою работу, блок управления страницами обратится к корректному набору Таблиц Страниц.
Отображение линейных адресов в физические превращается в механическую задачу, хотя она и остается довольно сложной. Следующие несколько разделов этой главы представляют довольно однообразный список функций и макросов, которые предоставляют ядру информацию, необходимую ему при поиске адресов и работе с таблицами, причем большинство функций состоит из одной или двух строк.