Ядро Linux в комментариях

Устройства свопинга


В Linux ведется отсортированный по приоритету список действительных устройств свопинга (и файлов, но для простоты в настоящем разделе мы часто называем «устройствами» и то, и другое). Когда возникает необходимость распределить страницу свопинга, Linux распределяет ее на устройстве свопинга с наивысшим приоритетом, которое еще не заполнено.

В системе Linux также выполняется циклический переход от одного незаполненного устройства свопинга с равным приоритетом к другому, то есть применяется ротация устройств свопинга, что позволяет повысить производительность свопинга путем распределения запросов страничного обмена по нескольким дискам. Во время ожидания, пока один диск выполняет первый запрос, второй запрос отправляется к следующему диску. Поэтому оптимальная настройка состоит в распределении разделов свопинга по нескольким аналогичным дискам и присвоении им одинакового приоритета; более медленные диски должны иметь более низкий приоритет.

Однако ротация может также замедлять свопинг. Если несколько устройств свопинга на одном и том же диске имеют одинаковый приоритет, приходится снова и снова перемещать головки чтения/записи диска от одного устройства свопинга на диске к другому; именно в такой ситуации печально знаменитый коэффициент различия в скорости между оперативной памятью и диском, составляющий порядка 1000000, почти невозможно замаскировать.

К счастью, системный администратор может избежать этой проблемы, правильно распределив приоритеты свопинга. Истинный наследник Unix, система Linux всегда предоставляет системному администратору возможность сделать свою жизнь невыносимой, но она также всегда позволяет стать истинным триумфатором.

Простейшая схема состоит в присвоении каждому устройству свопинга на одном и том же диске разных значений приоритета; это позволяет избежать наихудших ситуаций, но вместе с тем, вероятно, не будет являться наилучшим решением.

Однако, поскольку это несложно и позволяет избежать наихудшего варианта, такой принцип применяется в системе по умолчанию, если администратор сам не назначает приоритеты.


Устройства свопинга представлены типом struct swap_info_struct (строка ). Массив этих объектов struct swap_info определен в строке . Функции в различных файлах манипулируют и используют swap_info для управления свопингом; мы приступим к их изучению чуть позже. Однако эти функции станут намного более понятными, если вначале мы изучим некоторые члены объекта struct swap_info_struct:

  • swap_device. Номер устройства, на котором будет выполняться свопинг; он равен 0, если объект представляет файл, а не раздел.


  • swap_file. Файл или раздел свопинга, представляемый этим объектом.


  • swap_map. Массив для подсчета числа пользователей каждой страницы свопинга в пространстве свопинга; если это число равно 0, страница свободна.


  • swap_lockmap. Массив, который отслеживает, происходит ли в данный момент чтение из памяти или запись на диск размещенной на диске страницы, соответствующей каждому биту в этом массиве. Страницы во время ввода/вывода должны быть заблокированы, чтобы ядро не пыталось дважды выполнять ввод/вывод одной и той же страницы одновременно или совершать еще какие-то подобные глупости. Помните, что при любой возможности со вводом/выводом совмещается любая другая обработка, поэтому попасть в такую ситуацию совсем несложно.


  • lowest_bit и highest_bit. Отслеживают позиции первой и последней доступных страниц на устройстве свопинга. Это позволяет ускорить поиск, связанный с определением свободного элемента. Первая страница устройства— это заголовок, который не должен использоваться для свопинга, поэтому значение lowest_bit никогда не равно 0.


  • cluster_next и cluster_nr. Используются для более эффективной группировки страниц свопинга на диске.


  • prio. Приоритет этого устройства свопинга.


  • pages. Число страниц, доступных на устройстве.


  • max. Максимальное число страниц, которое разрешено использовать ядру на этом устройстве.


  • next. Позволяет реализовать односвязный список (который, как вы помните, ведется в порядке приоритетов) этих объектов в массиве swap_info. Таким образом, массив отсортирован логически, а не физически. Значение next — это индекс логически последующего элемента в списке или –1 в конце списка.


  • Член объекта swap_list, определенный в строке , включает индекс заголовка списка (т.е. его заглавный член — см. определение объекта struct swap_list_t в строке ); этот индекс равен –1, если список пуст. Он также включает член со сбивающим с толку названием next, который позволяет определить следующее устройство свопинга, на котором мы должны попытаться распределить страницу. Поэтому данный член next представляет собой итеративный курсор. Он равен –1, если список пуст или если в настоящее время пространство свопинга заполнено.


    Содержание раздела