Главная » Ядро Linux » Отображение верхней памяти

0

По определению, страницы верхней памяти не могут постоянно отображаться в адресное пространство ядра. Поэтому страницы памяти, которые были выделены с помощью функции alloc_page s () ,  пр и использовании флага    GFP    HIGHMEM могут не иметь логического адреса.

Для аппаратной платформы х86 вся физическая память свыше 896 Мбайт помечается как верхняя память, и она не может автоматически или постоянно отображаться в адресное пространство ядра, несмотря на то что процессоры платформы х86 могут адресовать до 4 Гбайт физической памяти (до 64 Гбайт при наличии расширения РАЕ6). После выделения эти страницы должны быть отображены в логическое адресное пространство ядра. Для платформы х86 страницы верхней памяти отображаются где-то между отметками 3 и 4 Гбайт.

Постоянное отображение

Для  того  чтобы  отобразить заданную структуру  page  в адресное   пространство ядра, необходимо использовать следующую  функцию.

void *kmap(struct page *page)

Эта функция работает  как  со страницами нижней, так и верхней  памяти. Если структура  page соответствует странице нижней памяти, то просто  возвращается виртуальный адрес.  Если  страница расположена в верхней  памяти, то создается постоянное отображение этой  страницы памяти и возвращается полученный логический

6   РАЕ — Physical Address Extension  (расширени е физическо й  адресации).  Эта функция процессоро в х86 позволяет  физическ и адресовать  до 36 разрядов   (64  Гбайт)  памяти,   несмотря  на то что размер виртуального   адресного   пространства соответствует  только  32  бит.

адрес. Функция  kmap ()  может переводить процесс  в  состояние ожидания, поэтому ее  можно вызывать только в контексте процесса.

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

void kunmap(struct page *page)

Данная функция отменяет отображение страницы памяти,  связанной с  параметром  page .

Временное отображение

В  случаях ,  когд а  необходим о  создат ь  отображени е  страни ц  памят и  в  адресно е пространство ,  а текущи й  контекс т н е може т переходит ь в состояни е ожидания ,  ядро предоставляе т  функци ю   временного отображении (которо е  такж е  называетс я   атомарным  отображением).  Существует  некоторо е  количеств о   зарезервированны х  постоянны х отображений ,  которы е  могут  временн о  выполнят ь  отображени е  "н а лету". Ядро може т  автоматическ и  отображат ь  страниц у верхне й  памят и  в  одн о  и з  зарезервиро ванны х  отображений .  Временно е  отображени е  може т  использоватьс я  в  коде ,  которы й  н е може т переходит ь в состояни е  ожидания ,  как,  например ,  контекс т прерывания ,  потом у чт о  полученно е  отображени е  никогд а н е  блокируется .

Установк а  временног о  отображени я    выполняетс я  с  помощь ю  следующе й  функции .

void *kmap_atomic(struct page *page, enum km_type type)

Парамет р  typ e — эт о одн о и з значени й  показанног о ниж е  перечисления ,  определенног о  в  файл е  <asm/kmap_types.h> ,  которо е описывае т цел ь временног о  отображения .

enum km_type { KM_BOUNCE_READ, KM_SKB_SUNRPC_DATA, KM_SKB_DATA_SOFTIRQ, KM_USER0,

KM_USER1, KM_BIO_SRC_IRQ, KM_BIO_DST_IRQ, KM_PTE0, KM_PTE1, KM_PTE2, KM_IRQ0, KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1,

KM TYPE_NR

);

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

функция также  запрещает преемптивность ядра,  что  необходимо потому,  что  отображения   являются уникальными для  каждого   процессора  (а  перепланирование может переместить задание для  выполнения на  другом  процессоре).

Отменить отображение можно  с помощью  следующей функции.

void kunmap_atomic(void *kvaddr, enum km_type type)

Эта  функция также  не  блокирующая.  На  самом  деле  для  большинства аппаратных платформ она  ничего  не  делает,  за  исключением разрешения  преемптивности  ядра, потому  что  временное  отображение действует   только   до  тех  пор,  пока  не  создано новое   временное отображение.  Поэтому ядро  просто   "забывает"   о  вызове  функции kmap_atomic () , и функции kunmap    atomi c ()  практически ничего  не нужно  делать. Следующее  атомарное  отображение  просто   заменяет  предыдущее.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии