zurück zum Artikel

Linux-Kernel 6.8.1: Korrekturen für Kernel 6.8

Oliver Müller

Linux-Kernel putzt sich heraus: Version 6.8.1 hat rasch 6.8 abgelöst.

(Bild: heise online)

Kernel 6.8 hat mehr zu bieten: etwa den ersten funktionsfähigen Treiber in Rust, ein optimierter Realtime-Scheduler und aufgepeppte TCP-Performance.

Linus Torvalds Release-Meldung gab für Linux 6.8 [1] keine großen Änderungen bekannt. Wer auf neue Dateisysteme, weltverändernde Features und Unmengen neuer unterstützter Hardware wartete, wird tatsächlich enttäuscht. Lediglich der neue Grafiktreiber für Intel Xe sticht für Torvalds in diesem Sinne als Novum hervor. Dennoch hat Linux 6.8 einiges an interessantem im Gepäck, wenngleich sich das meiste unter der Oberfläche verbirgt.

Zudem ist bereits Linux 6.8.1 erschienen. Das Update auf 6.8.1 wird allen Benutzern von Linux 6.8 dringend empfohlen. Es enthält wichtige Sicherheits- und Bugfixes.

Bislang war mit Rust im stabilen Linux-Kernel relativ wenig anzufangen. Ende 2022 feierte Rust zwar offiziell mit Kernel 6.1 [2] seinen Einstand. Nutzen konnte man das aber bislang für neue Module beziehungsweise Treiber nicht. Mit Linux 6.8 kommt nun der erste nutzbare, funktionsfähige und in Rust programmierte Treiber. Dieser Treiber unterstützt Fast-Ethernet-Controller von Asix Electronics vom Typ AX88796B. Die Hardware kommt hauptsächlich im Embedded-Bereich in industriellen Anwendungen zum Einsatz.

Linux hat bereits einen in C geschriebenen Treiber für AX88796B im Gepäck. Die Rust-Variante reimplementiert die Funktion des C-Pendants eins zu eins. Standardmäßig ist die C-Variante im Linux-Kernel vorausgewählt. Will man die Rust-Version, ist diese beim Konfigurieren des Kernels vor dem Build entsprechend über den Schalter AX88796B_RUST_PHY auszuwählen.

Es ist ein geschickter Schachzug, einen bereits existierenden und funktionierenden Treiber in Rust nachzubauen. Da der gleiche Treiber einmal in C und einmal in Rust vorliegt, lässt sich Rust direkt mit C im Praxistest vergleichen und sinnvoll testen. Bei einem neuen Treiber für eine bislang nicht unterstützte Hardware wäre das nicht möglich.

Zeitgleich schafft das Entwicklerteam den notwendigen Unterbau für physische Netzwerktreiber in Form der notwendigen Abstraktionsschichten. Zukünftige Netzwerktreiber lassen sich damit grundsätzlich wahlweise in C oder Rust programmieren.

Im Fokus bleibt bei Linux-Kernel das Scheduling, also das Verteilen von Rechenzeit auf die einzelnen konkurrierenden Prozesse. Nachdem bereits Linux 6.6 radikal den Standard-Scheduler [3] ausgetauscht hatte, legt Linux 6.8 in diesem Bereich noch mal nach.

Der mit Linux 6.6 eingeführte neue Scheduler EEVDF (Earliest Eligible Virtual Deadline First) erfährt ein Tuning. Mit dem Einführen eines Fastpath-Mechanismus lässt sich der zum Zuge kommenden Task effizienter auswählen. Das Ganze auch noch mit konstanter Größenordnung von O(1). Erste Tests zeigen, dass der "O(1) Fastpath" tatsächlich die Task-Selection und damit den Scheduler als solchen effizienter arbeiten lässt.

Im Echtzeit-Bereich optimiert der neue Kernel den Deadline-Scheduler. Dieser basiert auf dem recht einfachen Konzept der "POSIX Realtime Scheduling Classes". Die Echtzeit-Tasks geben an, wie viel Rechenzeit sie benötigen und bis wann sie ihre Arbeiten abgeschlossen haben müssen. Je nachdem, wie dringend solche Tasks abgeschlossen sein müssen, werden sie priorisiert und erhalten früher CPU-Zeit. Würde ein solches System ohne irgendwelche weitere Vorkehrungen laufen, könnte es passieren, dass die Echtzeit-Tasks die "normalen" verhungern lassen. Alles, was nicht den "Echtzeitstempel" hat, müsste hinten anstehen. Ein ausgelastetes System würde in dem Fall schnell als "hängend" wahrgenommen. Wohingegen die Echtzeitaufgaben abgearbeitet würden, könnten alle Kontrollmöglichkeiten wie Login, administrative Aufgaben starten etc. auf Dauer ausgebremst werden. Eine Einflussnahme auf das System wäre nicht mehr möglich. Ein Kaltstart wäre die einzige Lösung.

Um dem vorzubeugen, reserviert der Kernel einen festen Anteil an CPU-Zeit für diese niedrig priorisierten Tasks. Per Voreinstellung sind das fünf Prozent; 95 Prozent bleiben für die Echtzeitverarbeitung. Ein System hat damit unabhängig von der Auslastung immer genügend Ressourcen zum Administrieren. Die Lösung nennt sich "Realtime Throttling", also "Echtzeitdrosselung".

Diese Lösung ist allerdings alles andere als optimal. Diese reservierten fünf Prozent bleiben auch dann reserviert, wenn gar keine niedrig priosisierten Tasks auszuführen sind. Das System ist damit konstant fünf Prozent "idle", selbst wenn die Echtzeitprozesse dieses Quäntchen mehr an Leistung gut brauchen könnten.

Die neue Lösung präsentiert sich als "Deadline-Server". Statt fix CPU-Zeit zu reservieren, verfrachtet der Scheduler die niedrig priorisierten Tasks in eine separate Deadline-Klasse – den "Deadline-Server". Sie ist höher priorisiert als die POSIX-Realtime-Klassen, in der sich die Echtzeitprozsse tummeln. Damit nehmen die an sich "niedrig" priorisierten Tasks "höchst" bevorzugt am Echtzeitreigen teil und werden den Echtzeit-Tasks immer vorgezogen.

Der Clou offenbart sich erst auf den zweiten Blick. Der "Deadline-Server" deklariert für sich einen CPU-Bedarf von fünf Prozent. Damit ist er zunächst auch gedeckelt, sodass die Echtzeit-Tasks wie ursprünglich mindestens 95 Prozent der CPU-Zeit erhalten. Sollten im "Deadline-Server" gar keine Tasks zum Ausführen anstehen, erkennt das der Scheduler und verteilt die angeforderten, aber nicht beanspruchten fünf Prozent CPU-Zeit kurzerhand an die Echtzeit-Tasks. Somit ist einerseits sichergestellt, dass die "niedrig" priorisierten, aber administrativ wichtigen Tasks immer ausreichend CPU-Zeit erhalten. Andererseits liegen diese reservierten CPU-Ressourcen nicht einfach brach, wenn sie nicht benötigt werden.

Linux 6.8 reorganisiert einige Kern-Netzwerk-Strukturen wie socks, netdev, netns und mibs neu, um die Cache-Effizienz zu verbessern. Was langweilig und unspektakulär klingt, verspricht doch eine erhebliche TCP-Performance-Steigerung. Bei "vielen" parallelen Netzwerkverbindungen soll diese bis zu 40 % betragen. Leider erläutert das entsprechende Patch-Set nicht, was unter "vielen" parallelen Netzwerkverbindungen zu verstehen ist.

Das bpfilter-Subsystem war angetreten, um Firewall-Regeln vom Format für Packet-Filter (iptables) in Berkley Packet Filter (BPF) zu übersetzen. Bereits 2018 mit Linux 4.18 in den Kernel aufgenommen, konnte es keinen praxistauglichen Stand erreichen. Zudem ebbte das Interesse, daran zu arbeiten, zunehmend ab. Als Konsequenz entledigt sich der Kernel nun des bpfilter-Subsystems. Die Weiterentwicklung soll in einem eigenen Repository bei GitHub [4] erfolgen.

In den Anfängen von Linux und Unix war die Zahl der eingehängten (mounted) Dateisysteme überschaubar und statisch. Spätestens seit dem Siegeszug von Containern hat sich das geändert. Bei jedem Start eines Containers mountet das System Dateisysteme und hängt sie beim Herunterfahren des Containers wieder aus. Dabei müssen es nicht unbedingt die Container von Docker, LXC & Co. sein. Der Einsatz von AppImages oder snap reicht völlig aus, um die kommenden und gehenden Mounts zu erzeugen. Dafür war das Betriebssystem nicht ausgelegt und hatte über die Jahre kaum nachgezogen.

Natürlich lässt sich über /proc/self/mountinfo die aktuelle Liste der Dateisysteme samt systeminterner ID auslesen. Einerseits ist diese Liste aufwendiger zu verarbeiten und bei der Zunahme der dynamischen Mount-Einträge mehr und mehr ein unschönes Relikt. Andererseits sind die IDs der Dateisysteme dem "Verfall" unterworfen. Soll heißen: wird ein Dateisystem ausgehängt, wird seine ID wiederverwendet. IDs sind also nicht über die Laufzeit des Systems eindeutig. Grundsätzlich gäbe es keinen Grund fürs ID-Recycling, schon jetzt ist die ID ein 64-Bit-Wert, was mehr als 18 Trillionen Mount-Vorgänge abbilden könnte. Gäbe es da nicht einige Userspace-Programme, die (fälschlich) nur 32 Bit dieser ID verwenden. Unglücklicherweise ist systemd eines dieser Programme.

Einem Vorschlag von Miklos Szeredi folgend, führt Linux 6.8 zwei neue Systemcalls ein. listmount() gibt eine Liste der eingehängten Dateisysteme zurück. statmount() ruft die Details über einen Mount auf. Beide Systemcalls bauen auf einer neuen eindeutigen, nicht wiederverwendeten 64-Bit-ID auf. Das Einführen einer zusätzlichen ID ist notwendig, da der Stand der ursprünglichen ID durchs falsche Verwenden in den Userspace-Programmen ziemlich festgefahren ist. Die verkorkste ursprüngliche ID muss (vorerst) weiter existieren. Das System führt sie als "alte ID" fort. Sämtliche bestehenden Wege abseits der neuen Systemcalls bauen unverändert auf dieser alten ID auf.

XFS führt die notwendigen Arbeiten für eine zukünftige Online-Reparatur fort. Leider ist die Online-Reparatur, also bei eingehängtem Dateisystem, noch immer nicht möglich. bcachefs ist hier bereits einen Schritt weiter. Das Dateisystem wartet im neuen Kernel mit einem zwar noch nicht vollständigen, aber im begrenztem Rahmen funktionierenden Online-Check- und -Reparaturmechanismus auf. SMB (CIFS) erhält die Möglichkeit, Block- und Character-Special-Files zu erzeugen.

Linux 6.8 unterstützt nun die "Intel Trust Domain Extension" (TDX) auf Host-ebene. Damit soll es zukünftig möglich sein, in KVM durch TDX Hardware-geschützte virtuelle Maschinen ausführen zu können. Zudem wechselt das Security-Modul AppAmor (endlich) bei den Hashes zur Policy-Prüfung von SHA-1 auf SHA-256. Ebenfalls als Altlast ist das Entfernen von strlcpy() aus dem Kernel abgeschlossen.

Der neue Kernel Linux 6.8 ist kein großer Wurf, was neue für den Benutzer sichtbare Funktionalität angeht. Der erste funktionierende Treiber in Rust ist jedoch erwähnens- und testenswert. Die Geschwindigkeit bei der Integration von Rust ist enorm. Es wird spannend zu beobachten sein, was sich dort zukünftig finden wird.

Insgesamt stellt Linux 6.8 sich für die Zukunft auf. Den Mut, den Mount-Mechanismus anzupacken, zeugt von keiner Scheu davor, das System für neue Trends fit zu machen. Konsequent optimiert das Entwicklerteam den Kernel, wie die Arbeiten am Scheduler und der TCP-Implementierung zeigen.

(dmk [5])


URL dieses Artikels:
https://www.heise.de/-9658035

Links in diesem Artikel:
[1] https://www.heise.de/news/Linux-6-8-mit-modernem-Intel-Grafiktreiber-9652455.html
[2] https://www.heise.de/news/Linux-6-1-als-naechster-Langzeit-Kernel-erschienen-7393140.html
[3] https://www.heise.de/news/Linux-6-6-bringt-neuen-Scheduler-9350044.html
[4] https://github.com/facebook/bpfilter
[5] mailto:dmk@heise.de