Partager via


Configuration et utilisation de files d’attente verrouillées

Les nouveaux pilotes doivent utiliser l’infrastructure de file d’attente cancel-safe IRP de préférence pour les méthodes décrites dans cette section.

Les pilotes avec des threads dédiés à l’appareil ou des pilotes qui utilisent des threads de travail exécutifs, tels que la plupart des FSD système, sont les types de pilotes les plus susceptibles de gérer leur propre mise en file d’attente interne au moment de l’exécution des IRP dans une file d’attente verrouillée. Tous les pilotes PnP, y compris les pilotes WDM, doivent également mettre en file d’attente certains IRP en interne tout en effectuant des transitions PnP et d’état d’alimentation.

En règle générale, ces pilotes configurent une file d’attente verrouillée doublement liée ; chaque IRP contient un membre de type LIST_ENTRY, qu’un pilote peut utiliser pour lier deux fois les IRP qu’il détient actuellement. Un pilote ne peut pas mettre de la file d’attente pour les nouvelles tentatives s’il configure une file d’attente verrouillée liée de manière unique.

Un pilote doit configurer sa file d’attente verrouillée lors de l’initialisation du périphérique. La figure suivante illustre une file d’attente verrouillée doublement liée, les routines de prise en charge qu’un pilote doit appeler pour configurer une telle file d’attente, et un ensemble de routines ExInterlocked Xxx qu’un pilote peut appeler pour insérer des IRP dans et supprimer des irps de la file d’attente.

diagramme illustrant l’utilisation d’une file d’attente verrouillée.

Comme le montre cette figure, un pilote doit fournir le stockage pour la file d’attente elle-même et pour les éléments suivants afin de configurer une file d’attente verrouillée doublement liée :

  • Verrou de rotation exécutif, que le pilote doit appeler KeInitializeSpinLock pour initialiser. En règle générale, un pilote initialise le verrou de rotation lorsqu’il configure la ou les extensions de périphérique pour ses objets de périphérique dans sa routine AddDevice .

  • Tête de liste de la file d’attente, que le pilote doit initialiser en appelant InitializeListHead.

La plupart des pilotes qui utilisent des files d’attente verrouillées doublement liées fournissent le stockage nécessaire dans l’extension de périphérique d’un objet de périphérique créé par le pilote. La file d’attente et le verrou de rotation exécutif peuvent se trouver dans une extension de contrôleur (si le pilote utilise un objet contrôleur) ou dans un pool non paginé alloué par le pilote.

Pendant que le pilote accepte les demandes d’E/S, il peut insérer un IRP dans sa file d’attente en appelant l’une des routines de support suivantes si listHead est de type LIST_ENTRY, comme illustré dans la figure précédente :

ExInterlockedInsertTailList pour placer l’IRP à la fin de la file d’attente

ExInterlockedInsertHeadList pour placer l’IRP à l’avant de la file d’attente. Les pilotes appellent généralement cette routine uniquement lorsqu’ils doivent réessayer une demande particulière.

Le pilote doit passer des pointeurs vers l’IRP (ListEntry), ainsi que les pointeurs ListHead et les pointeurs de verrouillage exécutif (Lock) qu’il a précédemment initialisés, à chacune de ces routines ExInterlockedInsertXxxList . Seuls les pointeurs vers ListHead et Lock sont requis lorsque le pilote supprime une IRP en appelant ExInterlockedRemoveHeadList. Pour éviter les interblocages, le pilote ne doit pas tenir un ExecutiveSpinLock qu’il transmet à une routine ExInterlocked Xxx.

Étant donné qu’une file d’attente verrouillée est protégée par le verrou de rotation exécutif, le pilote peut insérer des IRP dans sa file d’attente doublement liée et les supprimer de manière sécurisée multiprocesseur de toute routine de pilote s’exécutant à une valeur inférieure ou égale à IRQL = DISPATCH_LEVEL.

Une file d’attente avec un ListHead de type LIST_ENTRY, comme illustré dans la figure précédente, est une liste doublement liée. Une liste avec un ListHead de type SLIST_HEADER est une liste séquencée et liée séparément. Un pilote initialise listHead pour une file d’attente imbriquée liée de manière séquencée en appelant ExInitializeSListHead.

Un pilote qui ne retente jamais d’opérations d’E/S peut utiliser ExInterlockedPushEntrySList et ExInterlockedPopEntrySList pour gérer sa mise en file d’attente des IRP en interne dans une file d’attente verrouillée séquentiellement liée. Tout pilote qui utilise ce type de file d’attente verrouillée doit également fournir un stockage résident pour un ListHead de type SLIST_HEADER et pour un ExecutiveSpinLock, comme illustré dans la figure précédente. Il doit initialiser le verrou de rotation et configurer sa file d’attente avant d’appeler ExInterlockedPushEntrySList pour insérer l’entrée initiale dans sa file d’attente.

Pour plus d’informations, consultez Gestion des priorités matérielles et des verrous de rotation. Pour connaître les exigences IRQL pour une routine de support spécifique, consultez la page de référence de la routine.