Поделиться через


Постановка в очередь и отключение irPs

Так как диспетчер ввода-вывода поддерживает асинхронные операции ввода-вывода в многопоточной системе, запросы ввода-вывода к устройству могут поступать быстрее, чем его драйвер может обработать их до завершения, особенно на многопроцессорных компьютерах. Следовательно, irPs, привязанные к любому конкретному устройству, должны быть поставлены в очередь в драйвере, когда его устройство уже занято обработкой другого IRP.

Поэтому для драйвера самого низкого уровня требуется одно из следующих компонентов:

  • Подпрограмма StartIo, которую диспетчер операций ввода-вывода вызывает для запуска операций ввода-вывода для irPs, помещенных драйвером в очередь IRP, поставляемую системой (см. IoStartPacket).

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

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

Драйверы более высокого уровня почти никогда не имеют процедур StartIo . Большинство промежуточных драйверов не имеют ни подпрограмм StartIo, ни внутренних очередей; Промежуточный драйвер обычно может передавать irP с допустимыми параметрами из своих подпрограмм диспетчеризации и выполнять любую постобработку, необходимую для любого IRP в своей процедуре IoCompletion .

Ниже описаны, в общем, некоторые рекомендации по проектированию для определения того, следует ли реализовать подпрограмму StartIo с внутренними очередями, управляемыми драйвером, или без нее для irP.

Подпрограммы StartIo в драйверах

Для периферийных компьютеров, способных одновременно обрабатывать только одну операцию ввода-вывода устройства, драйверы устройств могут реализовывать подпрограммы StartIo . Для этих драйверов диспетчер операций ввода-вывода предоставляет подпрограммы IoStartPacket и IoStartNextPacket для постановки в очередь и вывода из очереди IRP, поставляемой системой, и из нее.

Дополнительные сведения о процедурах StartIo см. в статье Написание процедуры StartIo.

Внутренние очереди для IRP в драйверах

Если устройство может поддерживать несколько одновременных операций ввода-вывода, драйвер устройства самого низкого уровня должен настроить внутренние очереди запросов и управлять собственной очередью irP. Например, системный последовательный драйвер поддерживает отдельные очереди для операций чтения, записи, очистки и ожидания на своих устройствах, так как поддерживает полнодуплексные последовательные устройства.

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

Дополнительные сведения см. в разделе Очереди IRP, управляемые драйвером.

Внутренняя синхронизация очередей

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

Драйвер, реализующий собственную структуру очереди, должен обеспечить синхронизацию доступа к очереди и удаление отмененных irP из очереди. Чтобы упростить эту задачу для модулей записи драйверов, очереди IRP с безопасной отменой предоставляют стандартную платформу, используемую при реализации очереди IRP. Дополнительные сведения см. в разделе Отмена безопасных очередей IRP . Это предпочтительный метод реализации очереди IRP.

Драйверы также могут реализовать всю синхронизацию очереди IRP и отменить логику явным образом. Например, драйвер может использовать заблокированную очередь. Подпрограммы диспетчеризации драйвера вставляют irp в заблокированную очередь, а созданный драйвером поток или обратный вызов рабочего потока драйвера удаляет их, вызывая подпрограммы поддержки ExInterlockedXxxList .

Например, драйвер системного контроллера гибких дисков использует заблокированную очередь. Выделенный устройством поток обрабатывает те же процедуры IRP, что и процедуры StartIo других драйверов устройств, и некоторые из той же обработки IRP, что и подпрограммы DpcForIsr других драйверов устройств.

Внутренние очереди с подпрограммами StartIo в драйверах

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

Исключением является драйвер порта SCSI, который имеет подпрограмму StartIo и управляет внутренними очередями irP. Диспетчер ввода-вывода помещает в очередь irp в подпрограмму StartIo драйвера порта в очереди устройств, связанной с созданным драйвером объектом устройства, который представляет адаптер SCSI HBA. Драйвер порта SCSI также настраивает очереди устройств для irP на каждом целевом устройстве (соответствующем логическому блоку SCSI) на любой управляемой адаптером шине SCSI на компьютере.

Драйвер порта SCSI использует свои дополнительные очереди устройств для хранения irP, отправленных из драйверов класса SCSI, в очередях LU, когда любое устройство в шине SCSI особенно занято. По сути, дополнительные очереди устройств, относящиеся к LU, позволяют драйверу порта SCSI сериализовать операции для разнородных устройств SCSI с помощью адаптера HBA, сохраняя при этом все устройства на шинах SCSI этого адаптера максимально загружены.