Compartilhar via


Configurando e usando filas interligadas

Os novos drivers devem usar a estrutura de fila IRP com segurança de cancelamento em preferência para os métodos descritos nesta seção.

Drivers com threads ou drivers dedicados ao dispositivo que usam threads de trabalho executivo, como a maioria dos FSDs do sistema, são os tipos mais prováveis de drivers para gerenciar seu próprio enfileiramento interno em tempo de execução de IRPs em uma fila intertravada. Todos os drivers PnP, incluindo drivers WDM, também devem enfileirar determinados IRPs internamente ao fazer transições de PnP e estado de energia.

Normalmente, esses drivers configuram uma fila interligada duplamente vinculada; cada IRP contém um membro do tipo LIST_ENTRY, que um driver pode usar para vincular duplamente IRPs que ele está mantendo no momento. Um driver não poderá redirecionar IRPs para novas tentativas se configurar uma fila interligada vinculada.

Um driver deve configurar sua fila intertravada na inicialização do dispositivo. A figura a seguir ilustra uma fila interligada duplamente vinculada, as rotinas de suporte que um driver deve chamar para configurar essa fila e um conjunto de rotinas Xxx ExInterlocked que um driver pode chamar para inserir IRPs e remover IRPs da fila.

diagrama ilustrando o uso de uma fila intertravada.

Como mostra essa figura, um driver deve fornecer o armazenamento para a própria fila e para o seguinte, a fim de configurar uma fila interligada duplamente vinculada:

  • Um bloqueio de rotação executivo, que o driver deve chamar KeInitializeSpinLock para inicializar. Normalmente, um driver inicializa o bloqueio de rotação quando configura as extensões do dispositivo para seus objetos de dispositivo em sua rotina AddDevice .

  • O cabeçalho da lista da fila, que o driver deve inicializar chamando InitializeListHead.

A maioria dos drivers que usam filas interligadas duplamente vinculadas fornece o armazenamento necessário na extensão de dispositivo de um objeto de dispositivo criado pelo driver. Em vez disso, a fila e o bloqueio de rotação executivo podem estar em uma extensão de controlador (se o driver usar um objeto de controlador) ou em um pool nãopagado alocado pelo driver.

Enquanto o driver está aceitando solicitações de E/S, ele pode inserir um IRP em sua fila chamando uma das seguintes rotinas de suporte se o ListHead for do tipo LIST_ENTRY, conforme mostrado na figura anterior:

ExInterlockedInsertTailList para colocar o IRP no final da fila

ExInterlockedInsertHeadList para colocar o IRP na frente da fila. Os motoristas geralmente chamam essa rotina somente quando precisam repetir uma solicitação específica.

O driver deve passar ponteiros para o IRP (ListEntry), bem como os ponteiros ListHead e executive spin lock (Lock) que ele inicializou anteriormente para cada uma dessas rotinas da ListaXxxExInterlockedInsert . Somente ponteiros para ListHead e Lock são necessários quando o driver desativa um IRP chamando ExInterlockedRemoveHeadList. Para evitar deadlocks, o driver não deve estar segurando um ExecutiveSpinLock que ele passa para qualquer rotina Xxx ExInterlocked.

Como uma fila intertravada é protegida pelo bloqueio de rotação executivo, o driver pode inserir IRPs em sua fila duplamente vinculada e removê-los de maneira segura de vários processadores de qualquer rotina de driver em execução em menos de ou igual a IRQL = DISPATCH_LEVEL.

Uma fila com um ListHead do tipo LIST_ENTRY, conforme mostrado na figura anterior, é uma lista duplamente vinculada. Uma com um ListHead do tipo SLIST_HEADER é uma lista sequenciada e vinculada. Um driver inicializa o ListHead para uma fila intertravada vinculada em sequência chamando ExInitializeSListHead.

Um driver que nunca tenta novamente as operações de E/S pode usar ExInterlockedPushEntrySList e ExInterlockedPopEntrySList para gerenciar sua fila de IRPs internamente em uma fila interlocked sequenciada e vinculada. Qualquer driver que usa esse tipo de fila interligada também deve fornecer armazenamento residente para um ListHead do tipo SLIST_HEADER e para um ExecutiveSpinLock, conforme mostrado na figura anterior. Ele deve inicializar o bloqueio de rotação e configurar sua fila antes de chamar ExInterlockedPushEntrySList para inserir a entrada inicial em sua fila.

Para obter mais informações, consulte Gerenciando prioridades de hardware e bloqueios de rotação. Para requisitos de IRQL para uma rotina de suporte específica, consulte a página de referência da rotina.