Linux 6.6 bringt neuen Scheduler
Der neue Linux-Kernel tauscht nach 15 Jahren den Scheduler aus. Leistungssteigerung und verbesserte Sicherheit hat er ebenfalls im Gepäck.
(Bild: heise online)
Beim letzten Linux-Kernel-Release des Jahres stehen Performance und Optimierung im Vordergrund. Mit dem Austausch des Standard-Schedulers nach 15 Jahren packen die Kernel-Entwickler einen essenziellen Teil des Kernels an. Die Programmierer ringen sich durch, Hardware-Sicherheitsfeatures zu nutzen und steigern die asynchrone I/O beträchtlich. Bei den Dateisystemen gibt es Verbesserungen, aber auch wehmütiger Abschied gehört zum neuen Linux-Release.
Schichtwechsel beim Scheduler
Der Scheduler ist in Linux verantwortlich, Prozessen Rechenzeit zu gewähren. Er lässt sie nach bestimmten Regel auf den Prozessorkernen im Zeitscheibenverfahren alle mal zum Zuge kommen. Seit 2007 mit Kernel 2.6.23 nimmt diese Aufgabe in der Regel der "Completely Fair Scheduler" (CFS) wahr. Er löste damals den einfacheren und in die Jahre gekommenen ursprünglichen Scheduler ab. Parallel arbeiten die Entwickler an alternativen Schedulern, beispielsweise für Real-Time-Aufgaben.
Wie das "Fair" beim CFS schon andeutet, ist der bisherige Scheduler bestrebt, möglichst gerecht und ausgeglichen den Prozessen die vorhandenen CPU-Ressourcen zu überlassen. Er überwacht, wie viel Rechenzeit die jeweiligen Prozesse bereits erhalten haben und ist bestrebt, die Prozesse auszuführen, die bislang weniger CPU-Zeit erhielten.
Auch auf einem Linux-System sind nicht alle Prozesse gleich. Systemkritische Prozesse müssen trotz aller Fairness beim Verteilen der Taktzyklen bevorzugt werden. Das lässt sich Unix-typisch über den nice-Wert (von Englischen "Niceness", Nettigkeit) steuern, der Prozesse höher und niedriger priorisiert.
Neue Herausforderungen
CFS leistet noch immer im Gros der Anwendungsfälle gute Arbeit. Er ist aber nicht perfekt. Mit dem technischen Fortschritt ergeben sich neue Anforderungen. Ein Prozess sollte beispielsweise möglichst selten von einer CPU zur anderen wandern. Bei jedem CPU-Wechsel sind System-Caches als Zwischenschritt erneut zu bemühen. Um das Maximum aus den Caches zu ziehen, also optimal und effizient zu nutzen, sollten Prozesse möglichst lange auf einer CPU verbleiben. Dem entgegen steht das Bestreben, alle Prozessoren und Kerne auszulasten: Also lieber die CPU wechseln, bevor sich alles an einem Prozessor staut und sich andere langweilen.
Weitere Komplexität lauert in hybriden Systemen, bei denen unterschiedliche Prozessoren zum Einsatz kommen – etwa bei Großrechnern CPUs für spezielle Lasten wie Datenbanken und Java. Aber auch bei Hybrid-Core-Architekturen wie Alder Lake der 12. Generation ist das Thema relevant, bei denen Kerne für hohe Leistung (P-Cores, Performance Cores) neben Kernen für niedrigere Workloads (E-Cores, Efficient Cores) mit weniger Leistungsaufnahme koexistieren.
Moderne Scheduler sollten dabei aber auch das Power-Management im Blick haben. Das Ideal der perfekt ausgereizten Hardware bringt nichts, wenn dadurch beispielsweise der Akku des Notebooks in kürzester Zeit leer läuft.
Videos by heise
Auch lässt sich dem CFS nicht mit auf den Weg geben, welche Anforderungen an die Reaktionszeit (Latenz, Latency) ein Prozess stellt. Der nice-Wert gibt zwar an, dass ein kritischer Prozess mit höherer Priorität mehr CPU-Zeit erhält. Er definiert jedoch nicht, wie schnell der Prozess diese CPU-Zeit auch erhält. Ein zeitkritischer Prozess mag wenig CPU-Zeit benötigen, aber benötigt diese sehr schnell. Mit dem nice-Wert des CFS ist das nicht abbildbar.
Mehr Fairness
Abhilfe soll nun der neu aufgenommene "Earliest Eligible Virtual Deadline First" (EEVDF) Scheduler schaffen. Im Grunde greift der Linux-Kernel an dieser Stelle eine Idee von 1995 der Forscher Ion Stoica und Hussein Abdel-Wahab der Old Dominion Univerity in Norfolk (Virginia) auf. Das Funktionsprinzip ist ähnlich zum Deadline-Scheduler, welcher ebenfalls im Linux-Kernel zur Verfügung steht. Anders als der bereits länger vorhandene Deadline-Scheduler ist der EEVDF kein Realtime-Scheduler. Er ist also nicht für den Betrieb von Echtzeitsystemen, sondern in der Tat für "normale" Systeme wie Desktops und Server vorgesehen.
Wie der CFS verteilt der neue Scheduler die Rechenzeit möglichst "fair" zwischen Prozessen. Alle erhalten den gleichen Anteil an zur Verfügung stehender CPU-Zeit. Über den nice-Wert lässt sich dieser Anteil zu Gunsten höher priorisierter Prozesse verschieben. Sie erhalten je nach Prioritätsunterschied zu den konkurrierenden Prozessen mehr Anteil an den verfügbaren Rechenkapazitäten. Bis hierhin unterscheiden sich CFS und EEVDF nicht.
Allerdings führt EEVDF im Gegensatz zu CFS darüber Buch, welche Prozesse tatsächlich die zustehende Rechenzeit erhalten haben. Denn ein errechneter (theoretischer) Anteil verschiebt sich Hardware-bedingt. Prozesse können somit retrospektiv praktisch mehr oder weniger ihrer zustehenden Rechenzeit erhalten haben. Das gleicht EEVDF aus, indem Prozesse, die zu wenig Ressourcen erhalten haben, in der nächsten Runde priorisiert werden und früher laufen dürfen. Prozesse mit anteilsmäßig zu viel Rechenzeit qualifizieren sich erst mal gar nicht fürs Ausführen in der nächsten Runde. Durch das Zurückstehen gleicht sich deren Wert für spätere Läufe wieder an.
Schneller zum Zug kommen
Durch das Schema hat jeder qualifizierte Prozess einen Wert erhalten, die "virtual deadline". Er setzt sich aus der vom Prozess ermittelten Laufzeit und seiner zustehenden Zeit zusammen. Je niedriger dieser Wert ist, desto früher muss und darf er laufen. Er landet weiter oben in der Warteschlange (Run-Queue).
Das Latenzproblem adressiert EEVDF nun mit einem sehr einfachen Trick. Der Scheduler führt einen zusätzlichen Wert zur Priorisierung ein; den "latency-nice". Je niedriger dieser Wert ist, desto dringlicher ist der Prozess auszuführen. Unkritische Prozesse erhalten einen hohen latency-nice-Wert.
Um nun die Reihenfolge in der Run-Queue anhand der Latenz zu priorisieren, addiert der Scheduler zur "virtual deadline" den latency-nice hinzu. Damit ändert sich die Reihenfolge in der Warteschlange zu Gunsten der kritischeren Prozesse. Das einfache Prinzip beruht auf zwei Fakten. Von zwei Prozessen mit gleicher "virtual deadline", aber unterschiedlichen latency-nice-Werten, wird der dringlichere mit niedrigerem latency-nice in Summe in der Warteschlange nach oben wandern. Er wird priorisiert. Die andere einfache Tatsache ist, dass kritische Prozesse tendenziell weniger Rechnenzeit erfordern. Sie haben ohnehin schon eine niedrigere "virtual deadline".
Der EEVDF kommt damit ohne Annahmen und Daumenregeln zurecht. Einfache Arithmetik auf Basis geschickt ermittelter praktischer Werte lässt ihn die Warteschlange füllen.
Schattenwirtschaft
Die Kernel-Entwickler konnten sich nach mehrjähriger Diskussion nun durchringen, Intels Hardware-Shadow-Stack zu nutzen. Statt Rücksprungadressen nur auf dem Aufrufstapel (Call-Stack) wie jeher abzulegen, gehen diese zusätzlich gespiegelt auf den geschützten Schattenstapel (Shadow-Stack). Beim Rücksprung liest der Prozessor die Rücksprungadresse sowohl vom normalen Call-Stack, als auch vom Shadow-Stack.
Ein Vergleich der beiden Werte zeigt an, ob der Call-Stack modifiziert wurde. Dies kann im Falle eines Bugs, aber auch bei einem Angriff über einen Pufferüberlauf geschehen. Eine Ungleichheit der Rücksprungadressen der beiden Stapel zeigt dies an. Der Prozessor löst dann eine Ausnahme (Fault) aus.
Ein Angriff lässt sich damit erkennen und dessen Folgen eindämmen. Da es ein Hardware-Feature ist und einen 64-Bit-Intel-Prozessor voraussetzt, ist es lediglich im 64-Bit-Kernel verfügbar.
Leistungsschub
Der Kernel legt zum Jahresschluss noch mal tempomäßig nach. Er verspricht bei asynchronen direkten I/O-Zugriffen eine Leistungssteigerung von bis zu 37 Prozent beim Datendurchsatz und bei der Latenz. Möglich machen das Verbesserungen und der Einsatz des System-Call-Interface io_uring.
Wieder Rust-Versionswechsel
Nachdem schon beim vorherigen Kernel die Rust-Versionen angehoben wurden, ist auch beim neuen Kernel ein Aktualisieren der Versionen nötig. Dieses erneute, für Kernel-Verhältnisse untypisch schnelle Upgrade in so kurzer Zeit war vor allem notwendig, um Allokator-Funktionen zu konsolidieren.
Auch bindgen musste aktualisiert werden, um LLVM 16 unterstützen sowie Noreturn-Funktionen aus C korrekt in Rust abbilden zu können. Letztere zeigen durch das Schlüsselwort __noreturn an, dass sie nichts an den Aufrufer zurückliefern und der folgende Code unerreichbar ist (eingeführt mit C11). Linux 6.6 setzt jetzt Rust 1.71.1 und bindgen 0.65.1 voraus.
Neben diesen infrastrukturellen Umbauten zeigt die Rust-Integration diesmal aber auch bei der API Fortschritte. Der Löwenanteil liegt dabei der auf "pinned-init API" zum Initalisieren von Strukturen (structs).
Dateisysteme
Der Hort der temporären Dateien – das tmpfs – kann nun mit Benutzer- und Gruppen-Quotas begrenzt werden. Projekt-Quotas sollen in Kürze folgen. Dem ausufernden Gebrauch lässt sich damit nun auch beim tmpfs ein Riegel vorschieben. Bislang war dies bei /tmp nur mit echtem Plattenspeicher dahinter möglich.
Das Urgestein der Netzwerkdateisysteme NFS legt auf Server-Seite mit delegierten Schreibzugriffen (write delegations) von NFSv4 nach. Damit können Nutz- und Metadaten effizienter in Caches zwischengespeichert werden. Das reduziert Netzwerk-Traffic und steigert die Leistung.
Der mit Linux 5.15 eingeführte Kernel-eigene SMB3-Server ksmbd ist nicht mehr als "experimentell" eingestuft. Das adelt den auf hohen Datendurchsatz ausgelegten Server für den produktiven Einsatz.
Das Journaling-Dateisystem XFS nutzt im neuen Kernel die mit Linux 5.17 eingeführten "Large Folios" der Speicherverwaltung. Der Page-Cache lässt sich damit für einige Anwendungsfälle optimieren und verspricht mehr Leistung. Zudem stellt XFS die Weichen für den lang erwarteten Online-Dateisystem-Check. Bislang müssen XFS-Dateisysteme für eine Reparatur ausgehängt sein. Linux 6.6 liefert die ersten wichtigen Bausteine, um einen "Heilungsprozess" auf bei gemountetem Dateisystem vornehmen zu können.
ReiserFS ist jetzt offiziell als "obsolet" markiert. Es erfährt keine Unterstützung und Weiterentwicklung mehr. Planmäßig soll es in 2025 seinen endgültigen Abschied aus dem Kernel nehmen. Spätestens jetzt sollten Anwender des Journaling-Veteranen den Umstieg planen.
Altlasten entsorgt
Mehr als überfällig war, dass das Kernel-Team rigoros die Unterstützung für den alten Data Encryption Standard (DES) über Bord wirft. Die alte Feistelchiffre unterstützt lediglich die heute unsichere Verschlüsselung mit 56 Bit und wurde schon vor Jahrzehnten durch den Advanced Encryption Standard (AES) abgelöst. Selbst die übergangsweise dreifach angewendete DES-Chiffre (Triple-DES beziehungsweise 3DES) fliegt an wesentlichen Stellen aus dem Kernel.
Betroffen sind davon das DES-basierte Authentifizieren mittels Kerberos und die Verschlüsselung mit DES und 3DES in SunRPC. DES ist jedoch bereits seit 2012 mit RFC 6649 in Kerberos als veraltet gebrandmarkt. Für 3DES folgte der Marker 2018 mit RFC 8429.
Das betrifft unter anderem das Netzwerkdateisystem NFS, welches auf SunRPC aufsetzt. Auch dieses unterstützt mit Linux 6.6 keine Authentifizierung auf Basis von DES. Betroffen sollten davon allenfalls Installationen aus historischem Interesse sein. Moderne Systeme und Netzwerkumgebungen sollten ohnehin schon seit Jahren nicht mehr auf die alten Chiffren angewiesen sein.
Voraussichtlich nächstes LTS-Release
Linux 6.6 ist das letzte stabile Kernel-Release in diesem Jahr. Somit ist es wahrscheinlich, dass der Tradition folgend diese Version der nächste LTS-Kernel mit Langzeitunterstützung (LTS = Long Time Support) werden wird. Er wird somit voraussichtlich länger aktiv gepflegt und mit Sicherheits-Updates versorgt. Zudem werden viele Linux-Distributionen in ihren auf Produktivbetrieb ausgelegten Varianten auf diese Version aufsetzen. Üblich ist dies beispielsweise bei Debian GNU/Linux, Ubuntu oder auch Proxmox.
Sollte sich diese Erwartung erfüllen, wird Linux 6.6 allerdings seit 2017 der erste LTS-Kernel sein, der wieder nur zwei Jahre Unterstützung erhält. Aufgrund des hohen Aufwands, Kernel sechs Jahre lang zu pflegen, kündigten die Linux-Entwickler im September dieses Jahres an, wieder auf den alten Zwei-Jahres-Zyklus beim LTS-Kernel zurückzukehren.
Zusammengefasst
Linux 6.6 unterliegt mit dem Wechsel vom CFS- zum EEVDF-Scheduler einem wesentlichen Umbau. Es findet der Tausch einer zentralen Komponente statt, die jetzt in der Praxis zeigen kann, was in ihr steckt.
Die infrastrukturelle Dynamik bei Rust ist enorm. Für Kernel-Verhältnisse ist diese gar extrem. Es sind dort noch viele Weichen zu stellen, bis die ersten echten Treiber und Kernel-Module als Rust-Code vom Stapel laufen werden.
Der Kernel 6.6 ist eine signifikante Weiterentwicklung und sicherlich kein simples Wartungs-Release. Als LTS-Kernel-Kandidat stellt er sicherlich eine gute Wahl dar.
Der Kernel steht auf kernel.org zum Download bereit. Alle Änderungen finden sich detailliert im Kernel-Changelog.
(dmk)