Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Как работает оборудование: шины, мосты, порты и интерфейсы
отображении ввода-вывода в память устройствам назначаются регионы адресного пространства для связи и управления. Например, на архитектуре х86 регистры данных первого параллельного порта находятся в порту ввода-вывода (I/O port) 0x378, тогда как на РРС в зависимости от реализации он может находиться в памяти по адресу ОхГООООЗОО. Для чтения из регистра данных первого последовательного порта на х86 мы исполняем ассемблерную инструкцию in al, 0x378. В этом случае мы активизируем линию управления для контроллера параллельного порта. Для шины это означает, что 0x378 - это не адрес в памяти, а порт ввода-вывода. Для чтения регистра данных первого последовательного порта на РРС мы выполняем ассемблерную инструкцию lbz гЗ, 0 (Oxf 0000300). Контроллер параллельного порта следит за шиной адресов1 и отвечает только на запросы от определенного диапазона адресов, при которых ОхГООООЗОО будет неудачным. С развитием персональных компьютеров все больше дискретных устройств ввода-вывода объединялось в единственный интегрированный Superio чипсет. Функции Superio обычно берет на себя южный мост (как в ALI M1543C). В качестве примера типичной функциональности, которую можно обнаружить в Superio-устройстве, рассмотрим SMSC FDC37C932. Он включает контроллер клавиатуры, таймер реального времени, устройство управления питанием, контролер гибких дисков, контроллер последовательного порта, параллельный порт, интерфейс IDE и ввод-вывод общего назначения. Другие южные мосты содержат интегрированный контроллер локальной сети, PCI Express, аудиоконтроллер и т. д. Новая архитектура систем Intel перешла к концепции хабов (hubs). Северный мост стал называться хабом контроллеров графики и памяти (Graphics and Memory Controller Hub, GMCH). Он поддерживает высокопроизводительные AGR- и DDR-контроллеры. С появлением PCI Express чипсеты Intel превратились в хаб-контроллер памяти (Memory Controller Hub) (MCH) для контроллеров графики и памяти DDR2. Южный мост стал называться хабом контроллера ввода-вывода (I/O Controller Hub, ICH). Эти хабы связаны через проприетарную шину точка-точка, называемую хабом архитектуры Intel (Intel Hub Architecture, ША). Более подробную информацию можно найти в описании чипсетов Intel 865G2 и 925ХЕ3. Рис. 5.2 иллюстрирует ICH. AMD перешла от старого стиля Intel с северным и южным мостами к технологии упаковки HyperTransport между основными компонентами чипсета. Для операционной системы HyperTransport является PCI-совместимым4. (См. описание чипсета AMD для серии чипсетов 8000.) Рис. 5.3 иллюстрирует технологию HyperTransport. 1 Наблюдение за шиной адресов также часто связывают с декодированием шины адресов. 2 http: //www.intel.com/design/chipsets/datashts/25251405.pdf. 3 http: //www.intel.com/design/chipsets/datashts/30146403.pdf. 4 См. описание чипсетов AMD серии 8000: http: //www.amd.com/us-en/Processors/ProductIn- Глава 5* Ввод-Вывод Рис. 5.2. Новый хаб Intel Apple, в PowerPC, использует проприетарный дизайн, называемый универсальной архитектурой материнской платы (Universal Motherboard Architecture, UMA). Целью UMA является использование одинаковых чипсетов на всех Мас-системах. Чипсет G4 включает «UniNorth-контроллер памяти и мост шины PCI» в качестве северного моста и «Key Largo I/O и контроллер дисковых устройств» в качестве южного моста. UniNorth поддерживает SDRAM, Ethernet и AGP. Южный мост Key Largo связан с UniNorht с помощью моста PCI-to-PCI, поддерживает шины ATA, USB, беспроводную локальную сеть (WLAN) и звук. Чипсет G5 включает системный контроллер программно-специфическую интегрированную цепь (Application Specific Intergated Circuit, ASIC), поддерживающую AGP и память DDR. Он связан с системным контроллером через шину HyperTransport с контроллером PCI-X и высокопроизводительным устройством ввода-вывода. Более подробно об этой архитектуре можно прочитать на страницах Apple для разработчиков. Имея этот базовый обзор основных системных архитектур, мы можем теперь сфокусироваться на интерфейсах, предоставляемых устройствами ядру. В гл. 1, «Обзор», Устройства
Рис. 5.3. AMD HyperTransport говорилось, что устройства представлены файлами в файловой системе. Разрешение файла, режимы и связанные с файловой системой системные вызовы, такие, как open () и read () применяются к этим специальным файлам точно так же, как и к обычным. Значение каждого вызова отличается в зависимости от обрабатываемого устройства и изменяется для обработчиков каждого типа устройств. Тем не менее детали обработки устройства сделаны прозрачными для программиста приложений и скрыты в ядре. Стоит сказать, что, когда процесс применяет системный вызов к файлу устройства, он приводится к одному из типов функций обработки устройства. Эти функции-обработчики определяются в драйвере устройства. Рассмотрим основные типы устройств. Устройства Существует два типа файлов устройств: файлы блочных устройств и файлы символьных устройств. Блочные устройства передают данные порциями, а символьные устройства (как следует из названия) передают данные по символу за один раз. Третий тип устройств, сетевые устройства, является специальным случаем, наследующим свойства как блочных, так и символьных устройств. При этом сетевые устройства не представляются файлами. Глава 5 • Ввод-Вывод Старый метод назначения устройствам номеров, когда старшие номера обычно связывались с драйверами устройств или контроллерами, а младшие номера были отдельными устройствами внутри контроллера, уступил место новому, динамическому методу, называемому devf s. Исторически эти старшие и младшие номера были 8-битовыми, что позволяло иметь немногим больше 200 статически выделенных главных устройств на всей планете. Блочные и символьные устройства представлялись списками по 256 вхождений. (Вы можете найти официальный список выделяемых чисел для основных и дополнительных устройств в /Documentation/devices. txt.) Файловая система устройств Linux (Linux Device Filesystem, devfs) присутствовала до версии ядра 2.3.46; devfs не включена по умолчанию в сборку ядра 2.6.7, но может быть включена через файл настройки с помощью CONFIG_DEVFS=Y. При включении devfs модуль может регистрировать устройство по его имени, а не по паре старшего и младшего номеров. Для совместимости devfs позволяет использовать старые старшие и младшие номера или генерировать уникальные 16-битовые номера устройств на любой конкретной системе. Обзор блочных устройств Как говорилось ранее, операционная система Linux рассматривает все устройства в качестве файлов. Любые полученные элементы от блочного устройства могут быть связаны случайным образом. Хорошим примером блочного устройства является дисковый привод. Файловая система для диска IDE называется /dev/hda. С /dev/hda. связан старший номер 3 и младший номер 0. Сам дисковый привод обычно обладает контроллером и по своей сути является электромеханическим устройством (т. е. имеющим движущиеся части). Раздел «Общая концепция файловых систем» в гл. 6, «Файловые системы», рассматривает основы конструкции жесткого диска. 5.2.1.1 Обобщенный слой блочных устройств Драйвер устройства регистрируется во время инициализации драйверов. При этом драйвер добавляется в таблицу драйверов ядра (driver table), а номер драйвера отображается в структуру block_device_operations. Структура block_device__operations хранит функции для запуска и остановки данного блочного устройства в системе: include/linux/fs.h 7 60 struct block_device_operations { 761 int (*open) (struct inode *, struct file *); 762 int (*release) (struct inode *, struct file *); 763 int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); 764 int (*media_changed) (struct gendisk *); 765 int (*revalidate_disk) (struct gendisk *); Устройства 766 struct module *owner; 767 }; Интерфейс блочных устройств похож на интерфейсы других устройств. Функции open () (строка 761) и release () (строка 762) - синхронные (т. е. запускаются сразу после завершения вызова). Наиболее важные функции, read () и write (), реализованы для блочных устройств особым способом из-за их механической натуры. Рассмотрим доступ к блоку данных с дискового привода. Время, требуемое на позиционирование головки над соответствующей дорожкой, и то, чтобы диск повернулся на требуемый блок, с точки зрения процессора является достаточно долгим. Эта задержка (latency) привела к идее создания системной очереди запросов (system request queue). Когда файловой системе требуется один или несколько блоков данных и они не находятся в локальном кеше страниц (page cache), она помещает запрос в очередь запросов и передает очередь на слой обобщенного блочного устройства. Слой обобщенного блочного устройства определяет наиболее эффективный способ механического получения (или сохранения) информации и передает ее драйверу жесткого диска. Очень важно, что в момент инициализации драйвер блочного устройства регистрирует обработчик очереди запросов в ядре (с помощью специального менеджера блочного устройства) для выполнения операций чтения-записи блочного устройства. Слой обобщенного блочного устройства работает как интерфейс между файловой системой и интерфейсом уровня регистров и позволяет с помощью оптимизации в очереди запросов на чтение и запись наилучшим образом использовать новые и более разумные устройства. Это достигается с помощью вспомогательных утилит запросов. Например, если устройство для данной очереди поддерживает команды очередей, операции чтения и записи оптимизируются для использования на данном оборудовании с помощью перераспределения запросов. В качестве примера оптимизации очереди может служить возможность установки того, сколько запросов могут находиться в очереди ожидания. Связь уровня приложений, слоя файловой системы, слоя обобщенного блочного устройства и драйвера устройства показана на рис. 5.4. Файл biodoc. txt в /Documentation/block содержит дополнительную информацию об этом слое и информацию об изменениях со времен старых версий ядра. 5.2.2 Очереди запросов и планировщик ввода-вывода Когда запросы на чтение и запись передаются по слоям через VFS, они проходят драйверы файловой системы и кеш страниц1 и заканчиваются входом в драйвер блокового устройства для выполнения настоящих операций ввода-вывода на устройстве, хранящем требуемые данные. 1 Этот переход описывается в гл. 6 Глава 5» Ввод-Вывод
ПРИЛОЖЕНИЕ fopen() fclose() fwrite() fread() БЛОКИ ЧТЕНИЯ БЛОКИ ЗАПИСИ Ореп() close() Рис. 5.4. Чтение-запись блоков Как упоминалось ранее, драйвер блочного устройства создает и инициализирует очередь запросов во время инициализации. Также во время инициализации определяется алгоритм планировки ввода-вывода, используемого для чтения и записи с обслуживаемого блочного устройства. Алгоритм планирования ввода-вывода также называется алгоритмом лифта (elevator algorithm). По умолчанию алгоритм планировки ввода-вывода определяется ядром во время загрузки и по умолчанию выбирается предварительный планировщик ввода-вывода Устройства (anticipatory I/O scheduler)1. Установкой параметра ядра elevator вы можете изменять тип планировщика ввода-вывода: • deadline. Предельный планировщик ввода-вывода. • поор. Безоперационный планировщик ввода-вывода. • as. Преждевременный планировщик ввода-вывода. На момент написания этой книги существует патч, делающий планировщик ввода-вывода полностью модульным. Применяя modprobe, пользователь может загружать модули и переключаться между ними на лету2. С этим патчем как минимум один планировщик должен быть откомпилирован с самим ядром. Перед тем как приступить к описанию работы планировщика ввода-вывода, нам нужно коснуться основ очередей запросов. Блочные устройства используют очереди запросов для упорядочения запросов ввода-вывода на блоки устройства. Некоторые блочные устройства, такие, как виртуальный диск в памяти, не испытывают большой нужды в упорядочении запросов на ввод-вывод, так как это только тормозит работу. Другие блочные устройства, такие, как жесткие диски, нуждаются в сортировке запросов, так как для них операции чтения и записи обладают большой задержкой. Как говорилось ранее, головка жесткого диска должна переместиться на нужную дорожку, что с точки зрения процессора происходит слишком медленно. Очереди запросов решают эту проблему, пытаясь организовать последовательность запросов чтения и записи блоков с помощью отсрочки запросов. Простой и понятной аналогией планировщика ввода-вывода является работа лифта3. Если приказ на остановку лифта получен через отданный приказ, вы получите лифт, эффективно перемещающийся с этажа на этаж; он может спуститься с верхнего этажа на нижний без промежуточных остановок. Отвечая на запросы, поступающие с той стороны, куда движется лифт, он увеличивает свою эффективность и удовлетворенность пассажиров. Аналогично запросы ввода-вывода к жестокому диску группируются вместе, чтобы избежать лишних задержек при перемещении головки взад-вперед. Все упомянутые планировщики ввода-вывода (безоперационный, предельный и преждевременный) реализуют эту базовую функциональность лифта. Следующий раздел рассматривает лифты подробнее. 1 Некоторые драйверы блочных устройств могут изменять свой планировщик ввода-вывода во время работы, 2 Более подробную информацию можно найти в сети по запросам «Jens Axboe» и «Modular 10 Shedulen>. 3 Именно благодаря этой аналогии планировщики ввода-вывода связаны с лифтами. Глава 5 • Ввод-Вывод 5.2.2.1 Безоперационный планировщик ввода-вывода Безоперационный планировщик ввода-вывода1 получает запросы и сканирует очередь, определяя, можно ли объединить их с уже существующими запросами. Это возможно, если новый запрос близок к существующему. Если новый запрос необходим для блока перед тем, для которого уже есть запрос, он добавляется в начало существующего запроса. Если новый запрос существует для блока после того, для которого уже есть запрос, он добавляется в конец существующего запроса. При нормальном вводе-выводе мы читаем файл с начала до конца, и поэтому большинство запросов сливаются с уже существующими запросами. Если безоперационный планировщик обнаруживает, что новый запрос нельзя слить с уже существующим, так как он находится недостаточно близко, планировщик ищет запрос между этими двумя позициями. Если новый запрос вызывает операции ввода-вывода для секторов между существующими запросами, он вставляется в очередь на найденную позицию. Если он не может быть помещен между существующими запросами, он добавляется в конец. 5.2.2.2 Предельный планировщик ввода-вывода Безоперационный планировщик2 страдает одним недостатком: при достаточно близких запросах новый запрос никогда не будет обработан. Многие новые запросы, близкие к существующим, будут слиты или вставлены между существующими элементами, а новый запрос будет отброшен и помещен в конец очереди ожидания. Предельный планировщик пытается решить эту проблему с помощью назначения каждому запросу предельного времени и, кроме того, использует две дополнительные очереди для эффективной обработки времени, а в остальном он похож по эффективности на безоперационный алгоритм для работы с диском. Когда приложение делает запрос на чтение, оно обычно ожидает выполнения запроса перед продолжением выполнения. Запрос на запись, наоборот, обычно не заставляет приложение ожидать; запись можно выполнить в фоновом режиме, когда приложение займется другими своими делами. Предельный планировщик ввода-вывода использует эту информацию для предпочтения операций чтения операциям записи. Очереди чтения и записи хранятся отдельно и сортируются по близости секторов. В очередях чтения и записи запросы сортируются по времени (FIFO). При поступлении нового запроса он помещается в очередь безоперационного планировщика. Затем запрос помещается в очередь чтения или записи в зависимости от типа операции ввода-вывода. Затем запрос обрабатывает предельный планировщик ввода-вывода, проверяя сперва предельное время обработки головы очереди чтения. Аналогично если голова очереди чтения не достигла своего предела, планировщик проверяет 1 Код безоперационного планировщика находится в drivers/block/noop-iosched. с. 2 Код предельного планировщика ввода-вывода находится в drivers/block/deadline-iosched.c. Устройства голову очереди записи; если предел достигнут, голова очереди обрабатывается. Стандартная очередь проверяется, только когда нет достигнувших предела элементов очередей чтения и записи, и обрабатывается как и для безоперационного алгоритма. Запросы на чтение истекают быстрее, чем запросы на запись: S с против 5 с по умолчанию. Эта разница в достижении предела операциями чтения и записи может привести к тому, что множество операций чтения могут вызвать голод обработки операций записи. Поэтому предельному планировщику с помощью параметров указывается максимальное количество операций чтения, которые можно обработать до обработки операции записи; по умолчанию это 2, но, так как последовательные запросы можно трактовать как один запрос, может произойти 32 операции чтения перед тем, как запрос на запись будет считаться испытывающим голод1. 5.2.2.3 Предварительный планировщик ввода-вывода Главной проблемой предварительного планировщика ввода-вывода является интенсивное поступление операций записи. Так как он нацелен на максимизацию эффективности чтения, запрос на запись может предваряться чтением, из-за чего головка диска перейдет на новую позицию, а затем для выполнения операции записи будет возвращаться назад, в начальную позицию. Предварительный планировщик ввода-вывода2 пытается предупредить следующую операцию и таким образом повысить производительность ввода-вывода. Структурно предварительный планировщик ввода-вывода похож на предельный планировщик ввода-вывода. У него есть очереди чтения и записи, организованные по принципу FIFO, и очередь по умолчанию, упорядоченная по близости секторов. Основная разница заключается в том, что после запроса на чтение планировщик не начинает сразу обрабатывать другие запросы. В течение 6 мс он ничего не делает, выполняя дополнительное предварительное чтение. Если поступает новый запрос к прилежащей области, он сразу обрабатывается. После периода предсказания планировщик возвращается к обычным операциям, как описано для предельного планировщика ввода-вывода. Этот период предсказания позволяет минимизировать задержку ввода-вывода с помощью переноса головки диска от одного сектора к другому. Как и для предельного планировщика ввода-вывода, алгоритм предварительного планировщика ввода-вывода настраивается несколькими параметрами. По умолчанию время ожидания для запроса на чтение равно 1/8 с, а время ожидания для запроса на запись -1/4 с. Два параметра управляют тем, когда следует выполнять проверки переключения между потоками чтения и записи3. Поток чтения проверяет истекшие запросы на запись каждые 1/4 секунды, а поток записи проверяет запросы на чтение каждые 1/16 секунды. 1 См. параметры функции в строках 24-27 deadline-iosched. с. 2 Код предварительного планировщика ввода-вывода находится в drivers/block/as-iosched. с. 3 См. определение параметров в строках 30-60 as-iosched. с. Глава 5* Ввод-Вывод По умолчанию планировщиком ввода-вывода является предварительный планировщик ввода-вывода, потому что он оптимизирован для большинства приложений и блочных устройств. Предельный планировщик ввода-вывода иногда лучше подходит для работы с базами данных или приложений, требующих высокой производительности при работе с жестким диском. Безоперационный планировщик ввода-вывода обычно используется в системах, где важно время поиска, таких, как встроенные системы, работающие с операционной памятью. Теперь перенесем свое внимание с различных планировщиков ввода-вывода в ядре Linux на саму очередь запросов и способ, которым блочные устройства инициализируют очереди прерываний. Очередь запросов В Linux 2.6 каждое блочное устройство имеет собственную очередь запросов, обрабатывающую запросы ввода-вывода к устройству. Процесс может обновлять очередь запросов устройства только в том случае, если заблокирует очередь запросов. Давайте рассмотрим структуру request__queue. include/linux/blkdev.h 270 struct reguest_queue 271 {
272 /* 273 * Объединение с головой очереди для разделения кеша 274 */ 275 struct list_head queue__head; 276 struct request *last_merge; 277 elevator_t elevator; 278
279 /* 280 * очередь запрашивает свободный список для записи и для чтения 281 */ 282 struct request_list rq; Строка 275 Популярное:
|
Последнее изменение этой страницы: 2016-03-25; Просмотров: 884; Нарушение авторского права страницы