Einführung in Drehsperren

Spinsperren sind kerneldefinierte, nur Kernelmodus-Synchronisierungsmechanismen, die als undurchsichtiger Typ exportiert werden: KSPIN_LOCK. Eine Drehsperre kann verwendet werden, um freigegebene Daten oder Ressourcen vor gleichzeitigem Zugriff zu schützen. Bei der Ausführung bei IRQL <= DISPATCH_LEVEL kann ein Treiber KeAcquireInStackQueuedSpinLock und KeReleaseInStackQueuedSpinLock verwenden, um die Drehungssperre als in die Warteschlange eingereihte Drehsperre abzurufen und freizugeben.

Alternativ können Aufrufer, die unter IRQL >= DISPATCH_LEVEL ausgeführt werden, KeAcquireSpinLockAtDpcLevel und KeReleaseSpinLockFromDpcLevel aufrufen, um eine bessere Treiberleistung zu erzielen.

Viele Komponenten verwenden Drehsperren, einschließlich Treibern. Jede Art von Treiber kann eine oder mehrere Drehsperren von Führungskräften verwenden. Die meisten Dateisysteme verwenden beispielsweise eine verriegelte Arbeitswarteschlange in der Geräteerweiterung des Dateisystemtreibers (FSD), um IRPs zu speichern, die sowohl von den Workerthread-Rückrufroutinen des Dateisystems als auch von der FSD verarbeitet werden. Eine verriegelte Arbeitswarteschlange ist durch eine Spin-Lock für Führungskräfte geschützt, wodurch die Konflikte zwischen der FSD aufgelöst werden, die versucht, IRPs in die Warteschlange einzufügen, und alle Threads gleichzeitig versuchen, IRPs zu entfernen. Als weiteres Beispiel verwendet der System-Floppycontrollertreiber zwei Leitende Drehsperren. Eine Drehsperre für Führungskräfte schützt eine verriegelte Arbeitswarteschlange, die mit dem gerätededizierten Thread dieses Treibers geteilt wird; die andere schützt ein Timerobjekt, das von drei Treiberroutinen gemeinsam genutzt wird.

In die Warteschlange eingereihte Drehsperren bieten eine bessere Leistung als normale Drehsperren für hohe Inhaltssperren auf Multiprozessorcomputern. Weitere Informationen finden Sie unter "Warteschlanged Spin Locks". Treiber können auch KeAcquireSpinLock und KeReleaseSpinLock verwenden, um eine Drehsperre als normale Drehsperre zu erwerben und freizugeben.

Um den Zugriff auf einfache Datenstrukturen zu synchronisieren, können Treiber jede der ExInterlockedXxx-Routinen verwenden, um den atomaren Zugriff auf die Datenstruktur sicherzustellen. Treiber, die diese Routinen verwenden, müssen die Drehungssperre nicht explizit abrufen oder freigeben.

Jeder Treiber, der über einen ISR verfügt, verwendet eine Unterbrechungs-Spin-Sperre, um alle Daten oder Hardware zu schützen, die zwischen seinem ISR und seinen SynchCritSection-Routinen gemeinsam genutzt werden, die in der Regel von den StartIo- und DpcForIsr-Routinen aufgerufen werden. Eine Unterbrechungs-Drehsperre ist dem Satz von Interruptobjekten zugeordnet, die erstellt werden, wenn der Treiber Io Verbinden Interrupt aufruft, wie in der Registrierung eines ISR beschrieben.

Befolgen Sie die folgenden Richtlinien für die Verwendung von Drehsperren in Treibern:

  • Stellen Sie den Speicher für alle Daten oder Ressourcen bereit, die durch eine Drehsperre geschützt sind, und für die entsprechende Drehungssperre im speicherinternen Systemspeicher (nicht ausgelagerter Pool, wie in der Abbildung "Virtuelle Speicherplätze und physischer Speicher ") dargestellt. Ein Treiber muss den Speicher für alle von der Geschäftsleitung verwendeten Spin-Sperren bereitstellen. Ein Gerätetreiber muss jedoch nicht den Speicher für eine Unterbrechungsdrehsperre bereitstellen, es sei denn, er verfügt über einen Multivector-ISR oder verfügt über mehrere ISR, wie in der Registrierung eines ISR beschrieben.

  • Rufen Sie KeInitializeSpinLock auf, um jede Drehsperre zu initialisieren, für die der Treiber Speicher bereitstellt, bevor er ihn verwendet, um den Zugriff auf die freigegebenen Daten oder Ressourcen zu synchronisieren, die er schützt.

  • Rufen Sie jede Supportroutine auf, die eine Drehsperre an einer entsprechenden IRQL verwendet, in der Regel bei <= DISPATCH_LEVEL für Führungsdrehsperren oder bei <= DIRQL für eine Unterbrechungsdrehsperre, die den Interruptobjekten des Treibers zugeordnet ist.

  • Implementieren Sie Routinen, die so schnell wie möglich ausgeführt werden, während sie eine Drehsperre halten. Keine Routine sollte eine Drehsperre für mehr als 25 Mikrosekunden enthalten.

  • Implementieren Sie niemals Routinen, die eine der folgenden Aktionen ausführen, während Sie eine Drehsperre halten:

    • Ursache für Hardware-Ausnahmen oder Auslösen von Software-Ausnahmen.

    • Versuchen Sie, auf ausgelagerten Speicher zuzugreifen.

    • Führen Sie einen rekursiven Aufruf aus, der zu einem Deadlock führen würde oder dazu führen könnte, dass eine Drehsperre länger als 25 Mikrosekunden gehalten wird.

    • Versuchen Sie, eine weitere Spin-Sperre zu erhalten, wenn dies zu einem Deadlock führen kann.

    • Rufen Sie eine externe Routine auf, die gegen eine der vorherigen Regeln verstößt.