- Lektsia - бесплатные рефераты, доклады, курсовые работы, контрольные и дипломы для студентов - https://lektsia.info -

Посмотрев на общую картину управления памятью, рассмотрим теперь, как в ядре реализовано управление памятью и как реализованы страницы.



Страницы

В качестве базовой единицы памяти, которой управляет менеджер памяти, страница об­ладает большим количеством состояний, за которыми необходимо следить. Например, ядру необходимо знать, когда страница становится свободной для повторного выделения. Для этого ядро использует описатель страниц. Каждой физической странице в памяти на­значается свой описатель страницы.

Этот раздел описывает различные поля в описателе страницы и то как их использует менеджер памяти. Структура страницы определена в include/linux/mm.h.

include/linux/mm.h

170 struct page {

171 unsigned long flags;
172

173 atomic_t count;

174 struct list_head list;

175 struct address_space *mapping;

176 unsigned long index;

177 struct list_head lru; 178

179 union {

180 struct pte_chain *chain;
181

182 pte_addr_t direct;

183 } pte;

184 unsigned long private; 185

196 #if defined(WANT_PAGE_VIRTUAL)

197 void *virtual;
198

199 #endif

200 };



Глава 4• Управление памятью


Flags

Атомарные флаги описывают состояние страниц фреймов. Каждый флаг представлен од­ним битом 32-битового значения. Некоторые вспомогательные функции позволяют нам манипулировать отдельными флагами и тестировать их. Кроме этого, некоторые вспомо­гательные функции позволяют нам получать доступ к значениям битов, соответст­вующих отдельным флагам. Сами флаги, как и вспомогательные функции, определены в include/linux/page-flags.h. Табл. 4.1 описывает некоторые флаги, которые могут быть установлены в поле flags структуры страницы.

Таблица 4.1. Значение flag для page->flags


Флаг


Описание


 


PG_locked

PG_error PG_referenced

PG__uptodate

PG_dirty PG_lru

PG_active PG_slab

PG_highmem


Страница заблокирована, и ее нельзя трогать. Этот бит используется при вводе-выводе на диск, устанавливается перед операцией ввода-вывода и снимается после нее

Обозначает, что для этой страницы произошла ошибка

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

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

Обозначает модифицированную страницу

Страница находится в списке наименее часто используемых [least recently used (lru) ]. См. более подробное описание структуры lru далее в этом разделе

Обозначает, что страница находится в списке активных страниц

Эта страница принадлежит к блоку памяти, созданному выделителем блоков, описывается в разделе «Выделение секций» в этой главе

Означает что эта страница находится в верхней области памяти (ZONE_HIGHMEM) и поэтому не может быть сразу отображена в виртуальное адресное пространство ядра. Страницы из верхней области памяти определяются во время загрузки в mem_init () (см. подробности в гл. 8, «Загрузка ядра»)


 


PG_checked


Элемент файловой системы ext2. Убран в версии 2.5


 


PG_arch_l


Бит архитектурно-специфического состояния страницы


Страницы



Таблица 4.1. Значение flag для page->flags (Окончание)

PG_reserved Помечает страницу, которую нельзя выгрузить в своп память, которая

не существует или выделена при загрузке системы

PG_private Обозначает, что страница верна и устанавливается, если

page->private содержит правильное значение

PG_writeback Обозначает, что страница перезаписывается

PG_mappedtodisk Эта страница содержит блоки, выделенные на системном диске

PG_reclaim Обозначает, что страницу можно перераспределить

PG_compound Обозначает, что страница является частью страницы более высокого

уровня

Count

Поле count служит в качестве счетчика ссылок на страницу. Значение 0 означает, что фрейм станицы доступен для повторного использования. Положительное значение оз­начает количество процессов, могущих получить доступ к данным этой страницы1.

List

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

Mapping

Каждая страница может быть ассоциирована со структурой address_space, хранящей информацию для отображения файла в память. Поле mapping является указателем на address_space, членом которого является данная страница; address_space - это набор страниц, принадлежащих объекту памяти (например, inode). Более подробно ис­пользование address_space описывается в гл. 7, «Планировщик и синхронизация ядра», в подразд. 7.14.

Iru

Поле Iru хранит указатели на следующий и предыдущий элементы в списке последних использованных (Least Recently Used, LRU). Этот список связан с перераспределением памяти и состоит из двух списков: active_list, содержащего используемые страни­цы, и inactive_list, хранящего страницы, годные для повторного использования.

1 Страница освобождается, когда хранимые в ней данные больше не требуются.



Глава 4 • Управление памятью


4.1.1.5 virtual

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

Составные страницы

Составные страницы - это страницы более высокого уровня. Для включения поддержки со­ставных страниц в ядре во время компиляции необходимо включить «Huge TLB Page Support». Составные страницы объединяют более одной страницы, первая из которых называется голов­ной страницей, а последняя хвостовой страницей. У всех составных страниц устанавливается бит PG_compound в page->f lags, a page->lru. next указывает на голову страницы.

Зоны памяти

Не все создаваемые страницы равноценны. На некоторых компьютерных архитектурах определены константы, в рамках которых можно использовать некоторые физические адреса. Например, на х86 некоторые шины ISA могут адресовать только 16 Мб оператив­ной памяти. Несмотря на то что на РРС таких констант нет, концепция зон памяти портируется и на эту платформу для упрощения архитектурно-независимой части кода. В архитектурно-зависимой части РРС кода эти зоны перекрываются. Другие подобные константы могут использоваться, если в системе присутствует больше оперативной па­мяти, чем можно адресовать линейным способом.

Зоны памяти составляются из фреймов страниц или физических страниц, поэтому фреймы страниц выделяются из определенных зон памяти. В Linux существует три зоны памяти: ZONE__DMA (использующая фреймы страниц DMA), ZONE_NORMAL (не DMA-страницы с виртуальным отображением в память) и ZONE_HIGHMEM (страницы, чьи адре­са не находятся в пространстве виртуальных адресов).

Описатель зоны памяти

Как и любой объект, управляемый ядром, зона памяти имеет структуру zone, хранящую всю информацию об этой зоне. Структура zone определена в include/linux/ mmzone.h. Далее мы рассмотрим поближе несколько наиболее часто используемых по­лей этой структуры:

1 Верхняя память - это физическая память, которая превышает адресуемое виртуально пространство. См. разд. 4.2, «Зоны памяти».


Зоны памяти



include/linux/mmzone.h бб struct zone {

70 spinlock_t lock;

71 unsigned long free_pages;

72 unsigned long pages_min/ pages_low, pages_high; 73

74 ZONE_PADDING (_padl_)
75

76 spinlock_t lru_lock;

77 struct list_head active_JList;

78 struct list_head inactive_list;

79 atomic_t refill_counter;

80 unsigned long nr_active;

81 unsigned long nr_inactive;

82 int all_unreclaimable; /* Все страницы закрепляются */

83 unsigned long pages_scanned; /* с момента последнего восстановления */ 84

85 ZONE_PADDING (_pad2_)

103 int temp_priority;

104 int prev__priority;

109 struct free_area free_area[MAX_ORDER];

135 wait_queue_head_t * wait_table;

13 6 unsigned long wait_table_size;

137 unsigned long wait_table_bits;

13 9 ZONE_PADDING (_pad3_)

157 } ____ cacheline_maxaligned_in_smp;

Lock

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