5.2.2 Передача и приём данных

Предыдущая  Содержание  Следующая V*D*V

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

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

 

1.Добавление пакетов в очередь. Это выполняется стеками протоколов.

2.Удаление пакетов из очереди. Операция вывода данных представляет собой буфер, который передаётся устройству интерфейсом передачи драйвера.

 

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

 

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

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

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

 

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

 

Если интерфейс передачи вашего драйвера останавливает извлечение из очереди qdisc из-за ограниченного размера буфера, то обработчик прерывания должен организовать программное прерывание для передачи пакетов из qdisc с помощью netif_wake_queue().

Тем не менее, если в оборудовании при вызове интерфейса передачи ещё есть место, так что он может быть снова вызван верхним уровнем, функция netif_stop_queue вызываться не должна.

 

В нашем примере драйвера мы должны остановить вызовы функции передачи драйвера устройства, пока не произошло прерывание конец передачи. Таким образом, в течении времени, пока передаётся пакет, стек более высокого уровня может только помещать пакеты в очередь qdisc; пакеты не могут быть удалены из qdisc.

Приём сравнительно проще; он выделяет память для skbuff и вызывает функцию netif_rx, которая осуществляет планирование программного прерывания для обработки пакета (смотри Распечатку 5.7).

 

Предыдущая  Содержание  Следующая