Чтение онлайн

на главную - закладки

Жанры

Разработка ядра Linux
Шрифт:

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

Подведем итоги. Стек ядра занимает одну или две страницы памяти, в зависимости от конфигурации, которая выполняется перед компиляцией ядра. Следовательно, размер стека ядра может иметь диапазон от 4 до 16 Кбайт. Исторически обработчики прерываний совместно использовали

стек прерванного ими процесса. При появлении стеков ядра размером в одну страницу памяти обработчикам прерываний были назначены свои стеки. В любом случае неограниченная рекурсия и использование функций вроде
alloca
явно не допустимы.

Честная игра со стеком

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

thread_info
, которая расположена в самом конце стека процесса (вспомните главу 3). За пределами стека все данные ядра могут пропасть. В лучшем случае при переполнении стека произойдет сбой в работе машины. В худших случаях может произойти повреждение данных.

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

Отображение верхней памяти

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

alloc_pages
, при использовании флага
__GFP__HIGHMEM
могут не иметь логического адреса.

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

66

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

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

Для того чтобы отобразить заданную структуру

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

void *kmap(struct page *page);

Эта функция работает как со страницами нижней, так и верхней памяти. Если структура

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

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

void kunmap(struct page *page);

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

page
.

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

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

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

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

Параметр

type
— это одно из значений показанного ниже перечисления, определенного в файле
<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_atomic
практически ничего не нужно делать. Следующее атомарное отображение просто заменяет предыдущее.

Поделиться:
Популярные книги

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Бывшие. Война в академии магии

Берг Александра
2. Измены
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Бывшие. Война в академии магии

Мастер клинков. Начало пути

Распопов Дмитрий Викторович
1. Мастер клинков
Фантастика:
фэнтези
9.16
рейтинг книги
Мастер клинков. Начало пути

Имя нам Легион. Том 8

Дорничев Дмитрий
8. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 8

Измена. Право на счастье

Вирго Софи
1. Чем закончится измена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на счастье

Начальник милиции 2

Дамиров Рафаэль
2. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции 2

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Измена. Мой заклятый дракон

Марлин Юлия
Любовные романы:
любовно-фантастические романы
7.50
рейтинг книги
Измена. Мой заклятый дракон

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Рождение победителя

Каменистый Артем
3. Девятый
Фантастика:
фэнтези
альтернативная история
9.07
рейтинг книги
Рождение победителя

Барону наплевать на правила

Ренгач Евгений
7. Закон сильного
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Барону наплевать на правила

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь