Compartilhar via


Problemas de confiabilidade para um driver de miniporto WavePci

Um driver de miniporto WavePci deve acompanhar os mapeamentos que recebe do driver de porta. Um driver de miniporto WavePci mantém sua lista de mapeamentos em uma estrutura de dados compartilhada entre threads de driver. Os threads de driver também devem compartilhar o acesso ao canal DMA para adicionar novos mapeamentos à fila de hardware e remover mapeamentos concluídos da fila. Para evitar a corrupção de dados, os miniportores usam bloqueios de rotação para serializar acessos a estruturas de dados compartilhadas e periféricos. Um bloqueio de rotação protege os dados compartilhados e a fila de hardware contra o acesso simultâneo por dois ou mais threads de driver.

Ao desenvolver a parte do driver que gerencia mapeamentos, os fornecedores devem prestar atenção especial aos pontos a seguir.

Bloqueios de rotação

Para evitar possíveis deadlocks, o driver de miniporto não deve manter seu próprio bloqueio de rotação ao chamar Portcls.sys para adquirir ou liberar mapeamentos. O driver de exemplo do Ac97 no WDK (Microsoft Windows Driver Kit) ilustra esse princípio. Antes de chamar IPortWavePciStream::GetMapping ou IPortWavePciStream::ReleaseMapping, o driver de exemplo chama KeReleaseSpinLock para liberar o bloqueio de rotação. Depois que a chamada GetMapping ou ReleaseMapping retornar, o driver chamará KeAcquireSpinLock para adquirir o bloqueio de rotação novamente. Entre as chamadas para liberar e adquirir o bloqueio de rotação, um thread de driver não deve assumir que ele tem acesso exclusivo à lista de mapeamentos. Acessar os dados compartilhados durante esse intervalo desprotegido é perigoso. Se o intervalo entre liberar e adquirir o bloqueio de rotação for pequeno, a probabilidade de os dados serem corrompidos por uma condição de corrida entre dois threads de driver também será pequena. Isso significa que as falhas resultantes são intermitentes e, portanto, difíceis de rastrear. Depois de liberar e adquirir um bloqueio de rotação, um driver bem escrito deve assumir que quaisquer ponteiros ou índices temporários usados anteriormente para acessar o conteúdo das estruturas de dados compartilhados não são mais válidos.

Cancelamento de IRP

A qualquer momento durante o processamento de um fluxo de reprodução ou captura, o cancelamento de um IRP pode fazer com que o sistema operacional revogue um ou mais mapeamentos adquiridos pelo driver de miniporto. Quando isso ocorre, o driver de porta chama o método IMiniportWavePciStream::RevokeMappings para notificar o driver de miniport. Para evitar reproduzir dados ou capturar dados nos mapeamentos revogados, o driver de miniporto precisa remover os mapeamentos de sua lista de software e da fila de hardware do controlador de DMA. Como a lista de software e a fila de hardware são compartilhadas entre threads de driver, alguns cuidados são necessários para executar essas operações de forma confiável.

Por exemplo, um conjunto de mapeamentos a serem revogados pode conter um mapeamento que acabou de ser lançado ou está prestes a ser liberado. Nesse caso, dois threads de driver podem tentar simultaneamente remover o mesmo mapeamento da fila de DMA. Se o driver não conseguir impedir o acesso simultâneo, o resultado poderá ser corrompido dos dados nos registros ou nas estruturas de memória que gerenciam a fila.

Para obter um exemplo de código de trabalho, consulte o driver de exemplo ac97 no WDK (Kit de Driver do Windows).