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


Очереди и отмена irPs

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

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

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

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

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

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

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

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

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

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

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

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

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

Дополнительную информацию см. в разделе Driver-Managed Очереди IRP.

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

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

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

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

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

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

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

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

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