Главная » Ядро Linux » Нижние половины

0

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

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

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

• Если  работа критична ко времени выполнения, то ее необходимо выполнять в обработчике прерыпания.

• Если  работа  связана с аппаратным обеспечением, то ее следует выполнить в обработчике прерывания.

• Если  для выполнения работы  необходимо гарантировать, что другое прерывание  (обычно с тем же номером) не прервет  обработчик, то работу нужно  выполнить в обработчике прерывания.

• Для всего остального работу стоит выполнять в обработчике нижней половины.

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

Когда нужно использовать нижние половины

Часто  не просто  понять, зачем  нужно  откладывать работу и когда именно ее нужно откладывать. Вам необходимо ограничить количество работы, которая выполняется  в обработчике прерывания,  потому  что обработчик прерывания выполняется при  запрещенной текущей  линии прерывания. Хуже того, обработчики, зарегистрированные с указанием флага  SA_INTERRUPT, выполняются при  всех запрещенных линиях  прерываний на локальном процессоре (плюс  текущая  линия прерывания запрещена глобально). Минимизировать время, в течение  которого прерывания запрещены, важно  для уменьшения времени реакции и увеличения производительности системы. Если  к этому добавить, что обработчики прерываний выполняются асинхронно  по отношению к другому коду, и даже по отношению к другим  обработчикам прерываний, то становится ясно, что нужно  минимизировать время  выполнения обработчика прерывания. Решение — отложить некоторую часть работы  на более поздний срок.

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

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

Многообразие нижних половин

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

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

В самом  начале  своего  существования операционная система  Linux предоставляла единственный механизм для обработки нижних половин, который так и назывался "нижние половины" ("bottom half"). Это название было понятно, так как существовало только  одно  средство  для выполнения отложенной обработки. Соответствующая инфраструктура называлась "ВН" и мы ее так дальше  и будем назвать, чтобы  избежать путаницы с общим  термином "bottom  half  (нижняя половина). Интерфейс ВН  был очень  простым, как  и большинство вещей  в те старые  добрые  времена. Он предоставлял статический список из 32 обработчиков нижних половин. Обработчик верхней  половины должен  был  отметить  какой  из  обработчиков нижних половин должен  выполняться путем  установки соответствующего бита  в 32-разрядном целом числе.  Выполнение каждого  обработчика ВН синхронизировалось глобально, т.е. никакие  два обработчика не могли  выполняться одновременно, даже на разных  процессорах.  Такой  механизм был простым в использовании, хотя и не гибким; простым в реализации, хотя представлял собой  узкое место  в плане  производительности.

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

Во время разработки серии ядер 2.3 разработчики ядра предложили механизм от-

ложенных прерываний1  (softirq) и механизм тасклетов (tasklet).

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

Отложенные прерывания это  набор  из  32 статически определенных обработчиков нижних половин,  которые могут одновременно выполняться на разных процессорах, даже  два  обработчика одного  типа  могут  выполняться параллельно. Тасклеты — это гибкие, динамически создаваемые обработчики нижних половин, которые являются надстройкой над механизмом отложенных прерываний и имеют ужасное  название, смущающее всех3.

1 Термин softirq  часто  переводится,  как  "программное   прерывание",  однако,   чтобы  не  вносить  путаницу  с синхронным и  программным и  прерываниям и  (исключительными ситуациями)  в этом  контексте  используется  терми н  "отложенное  прерывание".   (Прим.  ред.)

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

3 Он и не имеют  ничего  общего  с понятием task (задача).  Их следует понимать  как просты е в использовании  отложенные прерывани я  (softirq).

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

Еще больше запутывает ситуацию то, что некоторые  люди говорят о всех обработчиках нижних  половин  как о программных  прерываниях,  или отложенных прерываниях  (software interrupt,  или softirq). Другими словами,  они называют механизм отложенных прерываний  и в общем обработку нижних половин программными  прерываниями.  На таких людей лучше не обращать внимания,  они из той же категории, что и те, которые придумали название  "ВН" и тасклет.

Во время разработки ядер серии 2.5 механизм ВН был в конце концов выброшен, потому что все пользователи  этого механизма конвертировали  свой код для использования других интерфейсов  обработки нижних половин. В дополнение  к этому, интерфейс очередей заданий был заменен  на новый интерфейс  очередей отложенных действий  (work queue). Очереди отложенных действий— это простой и в то же время полезный  механизм,  позволяющий поставить некоторое  действие в очередь для выполнения  в контексте процесса в более поздний момент времени.

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

Таймеры ядра

Еще один механизм выполнения отложенной работы — это таймеры ядра. В отличие от механизмов, рассмотренных в этой главе, таймеры позволяют отсрочить работу на указанный интервал времени. Инструменты, описанные в этой главе, могут быть полезны для откладывания работы с текущего момента до какого-нибудь момента времени в будущем. Таймеры используются для откладывания работы до того момента, пока не пройдет указанный период времени.

Поэтому таймеры имеют другое назначение, чем механизмы, описанные в данной главе. Более полное обсуждение таймеров ядра будет приведено в главе 10, "Таймеры и управление временем".

Путаница с нижними половинами

Некоторая  путаница с обработчиками  нижних половин имеет место, но на самом деле — это только проблема названий.  Давайте снова вернемся к этому вопросу.

Термин "нижняя половина" ("bottom half") — это общий термин,  который касается операционных систем и связан с тем, что некоторая  часть процесса обработки прерывания  откладывается  на будущее. В операционной системе Linux сейчас этот термин означает то же самое. Все механизмы ядра, которые предназначены  для отложенной обработки,  являются обработчиками  нижних половин.

Некоторые люди также  называют обработчики нижних половин программными прерываниями иди  "soflirq", но  они  просто  пытаются досадить  остальным.

Термин "Bottom  Half" также  соответствует названию  самого  первого  механизма выполнения отложенных действий п операционной системе  Linux.  Этот  механизм  еще  называется  "ВН", поэтому  далее  так  будем  называть именно этот  механизм, а термин "нижняя половина" ("bottom half") будет касаться общего  названия. Механизм ВН  был  некоторое время  назад  выключен из употребления и полностью изъят  в ядрах серии  2.5.

Сейчас  есть три метода  для назначения отложенных операций: механизм отложенных  прерываний  (softirq), механизм тасклетов и механизм очередей отложенных действий. Тасклеты построены на основе  механизма softirq, а очереди  отложенных действий имеют  полностью отличную реализацию. В табл. 7.1 показана история обработчиков нижних половин.

Таблица 7.1 . Состояние обработчиков нижних половин

Механизм обработчиков                           Состояние

ВН                                                                Изъято в серии 2.5

Очереди заданий                                        Изъято в серии 2.5

Отложенные прерывания                         Доступно  начиная с серии  2.3

Тасклеты                                                    Доступно  начиная с серии  2.3

Очереди отложенных действий               Доступно  начиная с серии 2.3

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

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

По теме:

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