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

на главную

Жанры

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

В ядрах серий до 2.6 работа потоков

pdflush
выполнялась двумя другими потоками ядра
bdflush
и
kupdated
.

Поток пространства ядра

bdflush
выполнял фоновую обратную запись измененных страниц, когда количество доступной памяти становилось достаточно малым. Также был определен ряд пороговых значений, аналогично тому как это делается для демона
pdflush
. Демон
bdflush
возвращался к выполнению с помощью функции
wakeup_bdflush
, когда количество свободной памяти становилось меньше этих пороговых значений.

Между демонами

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

Так как демон

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

Потоки

bdflush
и
kupdated
и их функциональность сейчас заменены потоками
pdflush
.

Предотвращение перегруженности: для чего нужны несколько потоков

Один из главных недостатков решения на основе демона

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

В ядрах серии 2.6 эта проблема решается путем введения нескольких потоков

pdflush
. Каждый поток самостоятельно выполняет обратную запись страниц памяти на диск, что позволяет различным потокам
pdflush
работать с разными очередями запросов устройств.

Количество потоков изменяется в процессе работы системы в соответствии с простым алгоритмом. Если все существующие потоки

pdflush
оказываются занятыми в течение одной секунды, то создается новый поток
pdflush
. Общее количество потоков не может превышать значения константы
MAX_PDFLUSH_THREADS
, которая по умолчанию равна 8. И наоборот, если поток pdflush находился в состоянии ожидания больше одной секунды, то он уничтожается. Минимальное количество потоков равно, по крайней мере, значению константы
MIN_PDFLUSH_THREADS,
что по умолчанию соответствует 2. Таким образом, количество потоков
pdflush
изменяется динамически в зависимости от количества страниц, для которых необходима обратная запись, и загруженности этих потоков. Если все потоки
pdflush
заняты обратной записью, то создается новый поток. Это гарантирует, что ни одна из очередей запросов устройств не
будет перегружена, в то время как другие очереди устройств не так загружены и в них тоже можно выполнять обратную запись. Если перегрузка предотвращается, то количество потоков
pdflush
уменьшается, чтобы освободить память.

Всё это хорошо, но что если все потоки

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

В связи с усовершенствованием алгоритмов обратной записи страниц, включая введение демона

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

Коротко о главном

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

pdflush
.

На основании материала последних нескольких глав вы получили устойчивое представление о том, как выполняется управление памятью и файловыми системами. Теперь давайте перейдем к теме модулей и посмотрим, ядро Linux обеспечивает модульную и динамическую инфраструктуру для загрузки кода ядра во время работы системы.

Глава 16

Модули

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

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

Модуль "Hello, World!"

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

Может показаться банальным, но иметь возможность написать программу, которая выводит сообщение "Hello World!", и не сделать этого- просто смешно. Итак, леди и джентльмены, модуль "Hello, World!".

/*

* hello.c - модуль ядра Hello, World!

*/

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

/*

* hello_init - функция инициализации, вызывается при загрузке модуля,

* В случае успешной загрузки модуля возвращает значение нуль,

* и ненулевое значение в противном случае.

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

Лорд Системы 12

Токсик Саша
12. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 12

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Инферно

Кретов Владимир Владимирович
2. Легенда
Фантастика:
фэнтези
8.57
рейтинг книги
Инферно

Нефилим

Демиров Леонид
4. Мания крафта
Фантастика:
фэнтези
боевая фантастика
рпг
7.64
рейтинг книги
Нефилим

Девятое правило дворянина

Герда Александр
9. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Девятое правило дворянина

Странник

Седой Василий
4. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Странник

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Кодекс Охотника. Книга XXV

Винокуров Юрий
25. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга XXV

Рядовой. Назад в СССР. Книга 1

Гаусс Максим
1. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Рядовой. Назад в СССР. Книга 1

Счастливый торт Шарлотты

Гринерс Эва
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Счастливый торт Шарлотты

Отмороженный 3.0

Гарцевич Евгений Александрович
3. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 3.0

Огни Аль-Тура. Завоеванная

Макушева Магда
4. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Огни Аль-Тура. Завоеванная

Жребий некроманта 3

Решетов Евгений Валерьевич
3. Жребий некроманта
Фантастика:
боевая фантастика
5.56
рейтинг книги
Жребий некроманта 3