Книга: Разработка ядра Linux
Зоны
Зоны
В связи с ограничениями аппаратного обеспечения, ядро не может рассматривать все страницы памяти как идентичные. Некоторые страницы, в связи со значениями их физических адресов памяти, не могут использоваться для некоторых типов задач. Из-за этого ограничения ядро делит физическую память на зоны. Ядро использует зоны, чтобы группировать страницы памяти с аналогичными свойствами. В частности, операционная система Linux должна учитывать следующие недостатки аппаратного обеспечения, связанные с адресацией памяти.
• Некоторые аппаратные устройства могут выполнять прямой доступ к памяти (ПДП, DMA, Direct Memory Access) только в определенную область адресов.
• На некоторых аппаратных платформах для физической адресации доступны большие объемы памяти, чем для виртуальной адресации. Следовательно, часть памяти не может постоянно отображаться в адресное пространство ядра.
В связи с этими ограничениями, в операционной системе Linux выделяют три зоны памяти.
• ZONE_DMA
. Содержит страницы, которые совместимы с режимом DMA.
• ZONE_NORMAL
. Содержит страницы памяти, которые отображаются в адресные пространства обычным образом.
• ZONE_HIGHMEM
. Содержит "верхнюю память", состоящую из страниц, которые не могут постоянно отображаться в адресное пространство ядра.
Эти зоны определяются в заголовочном файле <linux/mmzone.h>
.
То, как используется разделение памяти на зоны, зависит от аппаратной платформы. Например, для некоторых аппаратных платформ нет проблем с прямым доступом к памяти ни по какому адресу. Для таких платформ зона ZONE_DMA
является пустой, и для всех типов выделения памяти используется зона ZONE_NORMAL
.
Как противоположный пример можно привести платформу x86, для которой устройства ISA[61] не могут выполнять операции DMA в полном 32-разрядном пространстве адресов, так как устройства ISA могут обращаться только к первым 16 Мбайт физической памяти. Следовательно, зона ZONE_DMA
для платформы x86 содержит только страницы памяти с физическими адресами в диапазоне 0-16 Мбайт.
Аналогично используется и зона ZONE_HIGHMEM
. To, что аппаратная платформа может отображать и чего она не может отображать в адресное пространство ядра, отличается для разных аппаратных платформ. Для платформы x86 зона ZONE_HIGHMEM
— это вся память, адреса которой лежат выше отметки 896 Мбайт. Для других аппаратных платформ зона ZONE_HIGHMEM
пуста, так как вся память может непосредственно отображаться. Память, которая содержится в зоне ZONE_HIGHMEM
, называется верхней памятью[62] (high memory). Вся остальная память в системе называется нижней памятью (low memory).
Зона ZONE_NORMAL
обычно содержит все, что не попало в две предыдущие зоны памяти. Для аппаратной платформы x86, например, зона ZONE_NORMAL
содержит всю физическую память от 16 до 896 Мбайт. Для других, более удачных аппаратных платформ, ZONE_NORMAL
— это вся доступная память. В табл. 11.1 приведен список зон для аппаратной платформы x86.
Таблица 11.1. Зоны памяти для аппаратной платформы x86
Зона | Описание | Физическая память |
---|---|---|
ZONE_DMA |
Страницы памяти, совместимые с ПДП | < 16 Мбайт |
ZONE_NORMAL |
Нормально адресуемые страницы | 16 - 896 Мбайт |
ZONE_HIGHMEM |
Динамически отображаемые страницы | > 896 Мбайт |
Операционная система разделяет страницы системной памяти на зоны, чтобы иметь пулы страниц для удовлетворения требований выделения памяти. Например, пул зоны ZONE_DMA
дает возможность ядру удовлетворить запрос на выделение памяти, которая необходима для операций DMA. Если нужна такая память, ядро может просто выделить необходимое количество страниц из зоны ZONE_DMA
. Следует обратить внимание, что зоны не связаны с аппаратным обеспечением— это логическое группирование, которое позволяет ядру вести учет страниц; памяти.
Хотя некоторые запросы на выделение памяти могут требовать страницы из определенной зоны, это требование не обязательно может быть жестким. Например, выделение памяти для ПДП требует страницы из зоны ZONE_DMA
, а для обычного выделения памяти могут подойти страницы как из зоны ZONE_NORMAL
так и из зоны ZONE_DMA
. Конечно, для удовлетворения запросов по обычному выделению памяти ядро будет стараться выделять страницы из зоны ZONE_NORMAL
, чтобы сохранить страницы в зоне ZONE_DMA
для случая, когда эти страницы действительно нужны, Если же наступает решающий момент (становится недостаточно памяти), то ядро может обратиться к любой доступной и подходящей зоне.
Каждая зона представлена с помощью структуры struct zone
, которая определена в файле <linux/mmzone.h>
в следующем виде.
struct zone {
spinlock_t lock;
unsigned long free_pages;
unsigned long pages_min;
unsigned long pages_low;
unsigned long pages_high;
unsigned long protection[MAX_NR_ZONES];
spinlock_t lru_lock;
struct list_head active_list;
struct list_head inactive_list;
unsigned long nr_scan_active;
unsigned long nr_scan_inactive;
unsigned long nr_active;
unsigned long nr_inactive;
int all_unreclaimable;
unsigned long pages_scanned;
int temp_priority;
int prev_priority;
struct free_area free_area[MAX_ORDER];
wait_queue_head_t *wait_table;
unsigned long wait_table_size;
unsigned long wait_table_bits;
struct per_cpu_pageset pageset[NR_CPUS];
struct pglist_data *zone_pgdat;
struct page *zone_mem_map;
unsigned long zone_start_pfn;
char *name;
unsigned long spanned_pages;
unsigned long present_pages;
};
Эта структура большая, но в системе всего три зоны и соответственно три такие структуры. Рассмотрим наиболее важные поля данной структуры.
Поле lock
— это спин-блокировка, которая защищает структуру от параллельного доступа. Обратите внимание, что она защищает только структуру, а не страницы, которые принадлежат зоне. Для защиты отдельных страниц нет блокировок, хотя отдельные части кода могут блокировать данные, которые могут оказаться в указанных страницах.
Поле free_pages
— это количество свободных страниц в соответствующей зоне. Ядро старается поддерживать свободными хотя бы pages_min
страниц зоны, если это возможно (например, с помощью вытеснения на диск).
Поле name
— это строка, оканчивающаяся нулем, которая содержит имя соответствующей зоны (что не удивительно). Ядро инициализирует указанное поле при загрузке системы с помощью кода, который описан n файле mm/page_alloc.с.
Три зоны имеют имена "DMA", "Normal" и "HighMem".
- Страницы памяти
- Зоны
- Получение страниц памяти
- Уровень слябового распределителя памяти
- Интерфейс слябового распределителя памяти
- Статическое выделение памяти в стеке
- Отображение верхней памяти
- Выделение памяти, связанной с определенным процессором
- Новый интерфейс percpu
- Когда лучше использовать данные, связанные с процессорами
- Какой способ выделения памяти необходимо использовать
- Описание зоны
- Пример конфигурационного файла зоны
- Формирование описания зоны
- Конфигурация зоны для обратного преобразования
- 6.2. Диапазоны
- Текстовые факторы (важные зоны документа)
- 12.11.1 Зоны
- Открываем наши «мертвые зоны»
- «Мертвой зоны» не существует
- 6.2.1. Открытые и замкнутые диапазоны
- Выйди из зоны комфорта Брайан Трейси
- 13.1.3. Национальные зоны и зоны общего пользования