Abwärtskompatibilität

Wie am Anfang des Kapitels bereits erwähnt wurde, bringt die Interrupt-Verarbeitung in Linux relativ wenig Inkompatibilitäten mit älteren Kernel mit sich. Es gibt aber doch einige Probleme, die wir hier besprechen wollen. Die meisten Änderungen sind zwischen den Kernel-Versionen 2.0 und 2.2 geschehen, seitdem ist das Interrupt-Handling auffällig stabil.

Unterschiede im 2.2-Kernel

Die größte Änderung seit der 2.2-Reihe war das Hinzufügen von Tasklets im Kernel 2.3.43. Vor dieser Änderung war der BH-Mechanismus die einzige Möglichkeit für Interrupt-Handler, Aufgaben zu einem späteren Zeitpunkt abarbeiten zu lassen.

Die Funktion set_current_state gab es in Linux 2.2 noch nicht (sysdep.h implementiert sie aber). Um den aktuellen Prozeßzustand zu ändern, mußte man die Task-Struktur direkt manipulieren, wie in:


current->state = TASK_INTERRUPTIBLE;

Weitere Unterschiede im 2.0-Kernel

In Linux 2.0 gab es sehr viel mehr Unterschiede zwischen schnellen und langsamen Handlern. Langsame Handler waren wegen des zusätzlichen Organisationsaufwandes im Kernel schon vor der Ausführung langsamer. Schnellere Handler waren nicht nur dadurch schneller, daß die Interrupts abgeschaltet blieben, sondern auch dadurch, daß vor dem Rücksprung aus dem Interrupt nicht nach unteren Hälften gesucht wurde. Die Verzögerung vor der Ausführung einer unteren Hälfte, die in einem Interrupt-Handler vorgemerkt wurde, konnte daher im 2.0-Kernel länger sein. Und schließlich mußten im 2.0-Kernel alle registrierten Handler entweder langsam oder schnell sein, wenn eine IRQ-Leitung gemeinsam genutzt werden sollte; die beiden Modi konnten nicht gemischt werden.

Die meisten SMP-Probleme existierten in 2.0 natürlich nicht. Interrupt-Handler konnten nur jeweils auf einer CPU ausgeführt werden, so daß es keinen Unterschied zwischen dem lokalen und dem globalen Abschalten von Interrupts gab.

Die Funktion disable_irq_nosync gab es in 2.0 noch nicht; außerdem durften die Aufrufe von disable_irq und enable_irq nicht verschachtelt werden.

Die atomaren Operationen waren in 2.0 anders. Die Funktionen test_and_set_bit, test_and_clear_bit und test_and_change_bit gab es gar nicht; statt dessen gaben set_bit, clear_bit und change_bit einen Wert zurück und funktionierten wie die modernen test_and_-Versionen. Für die Integer-Versionen war atomic_t einfach ein typedef auf int; und Variablen des Typs atomic_t konnten wie ints verarbeitet werden. Die Funktionen atomic_set und atomic_read gab es gar nicht.

Die Makros wait_event und wait_event_interruptible gab es in Linux 2.0 noch nicht.