Enfileiramento e remoção de IRPs
Como o gerenciador de E/S dá suporte a E/S assíncrona em um sistema multitarefa e multithread, as solicitações de E/S para um dispositivo podem entrar mais rápido do que seu driver pode processá-las até a conclusão, especialmente em computadores com vários processadores. Consequentemente, os IRPs associados a qualquer dispositivo específico devem ser enfileirados no driver quando seu dispositivo já estiver ocupado processando outro IRP.
Portanto, um driver de nível mais baixo requer um dos seguintes:
Uma rotina StartIo , que o gerente de E/S chama para iniciar operações de E/S para IRPs que o driver enfileira em uma fila IRP fornecida pelo sistema (consulte IoStartPacket).
Um mecanismo interno de enfileiramento e remoção de fila do IRP, que o driver usa para gerenciar IRPs que vêm mais rápido do que ele pode satisfazê-los. Os drivers podem usar filas de dispositivo, filas interligadas ou filas cancel-safe. Para obter mais informações, consulte Filas DE IRP gerenciadas pelo driver.
Apenas um driver de dispositivo de nível mais baixo que possa satisfazer e concluir todos os IRP possíveis em suas rotinas de expedição não precisa de rotina StartIo e nenhuma fila gerenciada por driver para IRPs.
Drivers de nível superior quase nunca têm rotinas StartIo . A maioria dos drivers intermediários não tem rotinas StartIo nem filas internas; Um driver intermediário geralmente pode passar IRPs com parâmetros válidos em de suas rotinas de expedição e fazer qualquer pós-processamento necessário para qualquer IRP em sua rotina IoCompletion .
O exemplo a seguir descreve, em geral, algumas das considerações de design para determinar se uma rotina StartIo deve ser implementada com ou sem filas internas gerenciadas por driver para IRPs.
Rotinas startio em drivers
Para dispositivos periféricos de computador capazes de lidar apenas com uma operação de E/S de dispositivo por vez, os drivers de dispositivo podem implementar rotinas StartIo . Para esses drivers, o gerenciador de E/S fornece rotinas IoStartPacket e IoStartNextPacket para enfileirar e desativar IRPs de e para uma fila IRP fornecida pelo sistema.
Para obter mais informações sobre rotinas StartIo , consulte Escrevendo uma rotina StartIo.
Filas internas para IRPs em drivers
Se um dispositivo puder dar suporte a mais de uma operação simultânea de E/S, seu driver de dispositivo de nível mais baixo deverá configurar filas de solicitação internas e gerenciar seu próprio enfileiramento de IRPs. Por exemplo, o driver serial do sistema mantém filas separadas para operações de leitura, gravação, limpeza e espera em seus dispositivos porque dá suporte a dispositivos seriais full-duplex.
Um driver de nível superior que envia solicitações para algum número de drivers de dispositivo subjacentes também pode manter filas internas de IRPs. Por exemplo, os drivers do sistema de arquivos quase sempre têm filas internas para IRPs.
Para obter mais informações, consulte Filas DE IRP gerenciadas pelo driver.
Sincronização de Fila Interna
Drivers com threads dedicados ao dispositivo e drivers de nível mais alto que usam threads de trabalho executivos (incluindo a maioria dos drivers do sistema de arquivos) geralmente configuram sua própria fila para IRPs. A fila é compartilhada pelo thread de driver ou pelo retorno de chamada de thread de trabalho fornecido pelo driver e por outras rotinas de driver que processam IRPs.
Um driver que implementa sua própria estrutura de fila deve garantir que o acesso à fila seja sincronizado e que os IRPs cancelados sejam removidos da fila. Para tornar essa tarefa mais simples para gravadores de driver, as filas IRP cancel-safe fornecem uma estrutura padrão que você pode usar ao implementar uma fila IRP. Consulte Cancel-Safe IRP Queues para obter mais informações. Esse é o método preferencial para implementar uma fila IRP.
Os drivers também podem implementar toda a sincronização de filas IRP e cancelar a lógica explicitamente. Por exemplo, um driver pode usar uma fila interligada. As rotinas de expedição do driver inserem IRPs na fila interligada e um thread criado pelo driver ou o retorno de chamada de thread de trabalho do driver os remove chamando as rotinas de suporte da ListaXxxExInterlocked .
Por exemplo, o driver do controlador de disquete do sistema usa uma fila interligada. Seu thread dedicado ao dispositivo lida com o mesmo processamento de IRPs que é feito pelas rotinas StartIo de outros drivers de dispositivo e alguns dos mesmos processamentos de IRPs que é feito pelas rotinas DpcForIsr de outros drivers de dispositivo.
Filas internas com rotinas StartIo em drivers
Um driver que gerencia suas próprias filas internas também pode ter uma rotina StartIo , mas não precisa. A maioria dos drivers de dispositivo de nível mais baixo tem uma rotina StartIo ou gerencia seu próprio enfileiramento de IRPs, mas não ambos.
Uma exceção a isso é o driver de porta SCSI, que tem uma rotina StartIo e gerencia filas internas de IRPs. O gerenciador de E/S enfileira IRPs para a rotina StartIo do driver de porta na fila do dispositivo associada ao objeto de dispositivo criado pelo driver que representa um HBA SCSI. O driver de porta SCSI também configura e gerencia filas de dispositivos para IRPs para cada dispositivo de destino (correspondente a uma unidade lógica SCSI) em qualquer barramento SCSI controlado por HBA no computador.
O driver de porta SCSI usa suas filas de dispositivo suplementares para manter os IRPs enviados para baixo dos drivers de classe SCSI em filas específicas de LU sempre que qualquer dispositivo em um barramento SCSI estiver particularmente ocupado. Na verdade, as filas de dispositivo complementares específicas de LU desse driver permitem que o driver de porta SCSI serialize operações para dispositivos SCSI heterogêneos por meio de um HBA, mantendo cada dispositivo nos ônibus SCSI do HBA o mais ocupado possível.