Compartilhar via


Prevenção de erros e deadlocks ao usar bloqueios de rotação

Embora uma rotina de driver mantenha um bloqueio de rotação, ela não pode causar uma exceção de hardware ou gerar uma exceção de software sem derrubar o sistema. Em outras palavras, o ISR de um driver e qualquer rotina SynchCritSection fornecida pelo driver em uma chamada para KeSynchronizeExecution não devem causar uma falha ou interceptação, como uma falha de página ou uma exceção aritmética, e não podem gerar uma exceção de software. Uma rotina que chama KeAcquireSpinLock ou KeAcquireInStackQueuedSpinLock também não pode causar uma exceção de hardware ou gerar uma exceção de software até que tenha lançado seu bloqueio de rotação executivo e não esteja mais em execução em IRQL = DISPATCH_LEVEL.

Rotinas de suporte e dados pagináveis

Ao manter um bloqueio de rotação, os drivers não devem chamar rotinas que acessam dados pagináveis. Lembre-se de que os drivers podem chamar determinadas rotinas de suporte que acessam dados pagináveis se e somente se suas chamadas ocorrerem durante a execução em um IRQL estritamente menor que DISPATCH_LEVEL. Essa restrição IRQL impede chamar essas rotinas de suporte enquanto mantém um bloqueio de rotação. Para requisitos de IRQL para qualquer rotina de suporte específica, consulte a página de referência da rotina.

Recursão

A tentativa de adquirir um bloqueio de rotação recursivamente é garantida para causar um deadlock: a instanciação de espera de uma rotina recursiva não pode liberar o bloqueio de rotação enquanto uma segunda instanciação gira, tentando adquirir o mesmo bloqueio de rotação.

As diretrizes a seguir descrevem como você usa bloqueios de rotação com rotinas recursivas:

  • A rotina recursiva não deve se chamar enquanto mantém um bloqueio de rotação ou não deve tentar adquirir o mesmo bloqueio de rotação em chamadas subsequentes.

  • Enquanto a rotina recursiva mantém um bloqueio de rotação, outra rotina de driver não deve chamar a rotina recursiva se a recursão pode causar um deadlock ou pode fazer com que o chamador mantenha o bloqueio de rotação por mais de 25 microssegundos.

Para obter mais informações sobre rotinas de driver recursivo, consulte Usando a pilha de kernel.

Aquisições aninhadas de bloqueio de rotação

Tentar adquirir um segundo bloqueio de rotação enquanto mantém outro bloqueio de rotação também pode causar deadlocks ou baixo desempenho do driver.

As diretrizes a seguir descrevem como os drivers devem manter bloqueios de rotação:

  • O driver não deve chamar uma rotina de suporte que use um bloqueio de rotação, a menos que um deadlock não possa ocorrer.

  • Mesmo que um deadlock não possa ocorrer, o driver não deve chamar uma rotina de suporte que usa um bloqueio de rotação, a menos que técnicas alternativas de codificação não possam fornecer desempenho e funcionalidade comparáveis do driver.

  • Se um driver fizer chamadas aninhadas para adquirir bloqueios de rotação, ele sempre deverá adquirir os bloqueios de rotação na mesma ordem sempre que for adquirido. Essa ordem ajuda a evitar deadlocks.

Em geral, evite usar bloqueios de rotação aninhados para proteger subconjuntos sobrepostos ou conjuntos discretos de dados e recursos compartilhados. Considere o que pode acontecer se um driver usar dois bloqueios de rotação executivos para proteger recursos discretos, como um par de objetos de temporizador que podem ser definidos individual e coletivamente por várias rotinas de driver. O driver travava intermitentemente em um computador SMP, sempre que uma das duas rotinas, cada uma segurando um bloqueio de rotação, tentava adquirir o outro bloqueio de rotação.

Para obter mais informações sobre como adquirir bloqueios de rotação aninhados, consulte Bloqueios, deadlocks e sincronização.