6. Nichtwiedereintritt von Interrupt-Handlern
Im vorherigen Abschnitt haben wir erwähnt, dass es manchmal notwendig ist, Interrupts zu maskieren, aber warum sollten wir diesen Interrupt maskieren? Dies liegt nicht daran, dass es technisch unmöglich ist, dieselbe Interrupt-Routine zu parallelisieren, sondern an Managementüberlegungen. Der Grund, warum neue Interrupts von demselben IRQ während der Interrupt-Verarbeitung blockiert werden müssen, liegt darin, dass der Interrupt-Handler nicht wiedereintrittsfähig ist, sodass derselbe Interrupt-Handler nicht parallel ausgeführt werden kann. Hier geben wir ein Beispiel. Anhand dieses Beispiels können wir erkennen, dass die Treibersperre wahrscheinlich auftritt, wenn ein Interrupt-Handler parallelisiert werden kann. Wenn der Treiber gesperrt ist, stürzt Ihr Betriebssystem nicht unbedingt ab, aber das vom gesperrten Treiber unterstützte Gerät kann nicht mehr verwendet werden – wenn der Gerätetreiber ausfällt, stirbt auch das Gerät.
Das Ereignis, das PS1 auslöst, führt dazu, dass A1 einen Interrupt generiert, dann liest B1 die vorhandenen Daten in R1 und dann schreibt der Code C1 Daten in R2. Das Ereignis, das PS2 auslöst, veranlasst A2, einen Interrupt zu generieren, dann löscht B2 die Daten in R1 und dann liest C2 die Daten in R2.
Wenn PS1 zuerst generiert wird und wenn PS2 generiert wird, generiert A2 einen Interrupt und unterbricht PS2 (hängt dann am Ende der Task-Warteschlange). R1 wurden gelöscht. Wenn PS2 zu C2 läuft, wird C2 hier angehalten, da C1 noch keine Daten auf R2 geschrieben hat, und PS2 schläft auf Code C2, bis es durch ein Signal geweckt wird, wenn Daten lesbar sind. Dies liegt daran, dass die Daten in R1, die B2 in PS1 ursprünglich lesen wollte, von B2 in PS2 gelöscht wurden, sodass die PS1-Seite auf B1 ruht, bis sie durch ein Signal geweckt wird, wenn Daten zum Lesen vorhanden sind. Auf diese Weise wird das Ereignis, das PS1 und PS2 aufweckt, nie eintreten, sodass PS1 und PS2 gesperrt sind.
Da sich der Gerätetreiber mit den Geräteregistern befassen muss, ist es schwierig, wiedereintrittsfähigen Code zu schreiben, da es sich bei den Geräteregistern um globale Variablen handelt. Daher besteht der einfachste Weg darin, die Parallelität der Interrupt-Handler desselben Geräts zu verhindern, dh der Interrupt-Handler des Geräts ist nicht wiedereintrittsfähig.
Eines muss klar sein: Im Linux-Kernel nach Version 2.0 sind alle oberen Hälften unterbrechungsfrei (die Operationen der oberen Hälfte sind atomar); die unteren Hälften verschiedener Geräteabschnitte können sich gegenseitig unterbrechen, aber Eine bestimmte untere Hälfte kann nicht allein unterbrochen werden (d. h. dieselbe untere Hälfte kann nicht parallel sein).
Da Interrupt-Handler nicht wiedereintrittsfähig sein müssen, müssen sich Programmierer keine Gedanken über das Schreiben von wiedereintrittsfähigem Code machen. Meiner Erfahrung nach ist das Schreiben wiedereintrittsfähiger Gerätetreiber möglich, aber das Schreiben wiedereintrittsfähiger Interrupt-Handler ist sehr selten und fast unmöglich.
7. Vermeiden Sie das Auftreten von Race Conditions
Wir alle wissen, dass es beim Eintreten einer Race Condition zu einem Deadlock kommen kann und in schweren Fällen das gesamte System gesperrt werden kann. Vermeiden Sie daher unbedingt Rennbedingungen. Ich werde hier nicht viel sagen, aber jeder muss nur auf eines achten: Die meisten durch Interrupts verursachten Race Conditions werden durch den Kernel-Prozess verursacht, bei dem Interrupts in den Ruhezustand versetzt werden. Daher müssen Sie bei der Implementierung von Interrupts darauf achten, den Prozess in den Ruhezustand zu versetzen. Bei Bedarf können Sie cli, sti oder save_flag, restart_flag verwenden. Spezifische Einzelheiten entnehmen Sie bitte dem in diesem Artikel genannten Nachschlagewerk.
8. Implementierung
Wie die Interrupt-Routine des Treibers implementiert wird, bleibt den Lesern überlassen. Solange Sie den Quellcode der kurzen Routine sorgfältig lesen und die Regeln zum Schreiben von Treiber-Interrupt-Routinen verstehen, können Sie Ihre eigene Interrupt-Routine schreiben. Solange die Konzepte korrekt sind und Ihr Code nach den richtigen Regeln geschrieben ist, ist es sinnvoll. Ich betone immer, dass Konzepte an erster Stelle stehen und wie viel Code geschrieben werden kann, zweitrangig ist. Wir müssen die richtigen Konzepte haben, um richtig denken zu können.
(T114)
Das Obige ist die ausführliche Analyse von Linux-Gerätetreiber-Interrupts (1) (3). Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www .php.cn)!