Problèmes de fiabilité pour un pilote WavePci Miniport
Un pilote de miniport WavePci doit effectuer le suivi des mappages qu’il reçoit du pilote de port. Un pilote miniport WavePci conserve sa liste de mappages dans une structure de données partagée entre les threads de pilote. Les threads de pilote doivent également partager l’accès au canal DMA pour ajouter de nouveaux mappages à la file d’attente matérielle et supprimer les mappages terminés de la file d’attente. Pour empêcher l’altération des données, les pilotes miniport utilisent des verrous de rotation pour sérialiser les accès aux structures de données et aux périphériques partagés. Un verrou de rotation protège la file d’attente des données et du matériel partagés contre l’accès simultané par au moins deux threads de pilote.
Lors du développement de la partie du pilote qui gère les mappages, les fournisseurs doivent accorder une attention particulière aux points suivants.
Verrous de rotation
Pour éviter les interblocages potentiels, le pilote miniport ne doit pas contenir son propre verrou tournant lors de l’appel de Portcls.sys pour acquérir ou libérer des mappages. L’exemple de pilote Ac97 dans le Kit de pilotes Microsoft Windows (WDK) illustre ce principe. Avant d’appeler IPortWavePciStream::GetMapping ou IPortWavePciStream::ReleaseMapping, l’exemple de pilote appelle KeReleaseSpinLock pour libérer le verrou de rotation. Une fois l’appel GetMapping ou ReleaseMapping retourné, le pilote appelle KeAcquireSpinLock pour acquérir à nouveau le verrou de rotation. Entre les appels à la mise en production et à l’acquisition du verrou de rotation, un thread de pilote ne doit pas supposer qu’il dispose d’un accès exclusif à la liste des mappages. L’accès aux données partagées pendant cet intervalle non protégé est dangereux. Si l’intervalle entre la libération et l’acquisition du verrou de rotation est faible, la probabilité que les données soient endommagées par une condition de concurrence entre deux threads de pilote est également faible. Cela signifie que les défaillances résultantes sont intermittentes et donc difficiles à tracer. Après avoir libéré et acquis un verrou de rotation, un pilote bien écrit doit supposer que les pointeurs ou index temporaires qu’il utilisait précédemment pour accéder au contenu des structures de données partagées ne sont plus valides.
Annulation D’IRP
À tout moment pendant le traitement d’un flux de lecture ou de capture, l’annulation d’un IRP peut amener le système d’exploitation à révoquer un ou plusieurs mappages acquis par le pilote miniport. Dans ce cas, le pilote de port appelle la méthode IMiniportWavePciStream::RevokeMappings pour notifier le pilote miniport. Pour éviter de lire ou de capturer des données dans les mappages révoqués, le pilote miniport doit supprimer les mappages de sa liste de logiciels et de la file d’attente matérielle du contrôleur DMA. Étant donné que la liste des logiciels et la file d’attente matérielle sont partagées entre les threads de pilotes, une certaine prudence est nécessaire pour effectuer ces opérations de manière fiable.
Par exemple, un ensemble de mappages à révoquer peut contenir un mappage qui vient d’être ou est sur le point d’être publié. Dans ce cas, deux threads de pilote peuvent simultanément tenter de supprimer le même mappage de la file d’attente DMA. Si le pilote ne parvient pas à empêcher l’accès simultané, le résultat peut être une altération des données dans les registres ou les structures de mémoire qui gèrent la file d’attente.
Pour obtenir un exemple de code fonctionnel, consultez l’exemple de pilote Ac97 dans le Kit de pilotes Windows (WDK).