Linux 6.3: Wegbereiter für die Abkehr von C

Linux 6.3 öffnet mit eBPF und Rust den Blick auf Horizonte jenseits von C. Zudem zieht es bei Jumbopaketen und gemischten Subflows bei Multipath TCP nach.

In Pocket speichern vorlesen Druckansicht 134 Kommentare lesen

(Bild: heise online)

Lesezeit: 10 Min.
Von
  • Oliver Müller
Inhaltsverzeichnis

Die aktuell nutzbaren Features des neuen Linux 6.3 lassen das Kernel-Release äußerlich wie ein Wartungs-Release erscheinen. Im Inneren bahnen sich jedoch größere Umbrüche an.

Von einigen architekturspezifischen Teilen in Assembler abgesehen, ist der Linux-Kernel in der Programmiersprache C geschrieben. Neue Funktionen und Treiber konnten nur als C-Code einfließen. Was lange als gesetzt galt, weicht zunehmend auf. Neben den rasanten Schritten, Rust in den Kernel zu integrieren, mausert sich auch eBPF zunehmend zu einer Alternative, um vormals C vorbehaltene Funktionalität in den Kernel bringen.

Linux 6.3 ermöglicht den Zugriff auf die "Red-Black Trees" des Kernels (rbtrees) aus eBPF-Programmen heraus. Die rbtrees sind eine Form von binären Suchbäumen, die der Kernel intensiv an vielen Stellen nutzt, unter anderem in Dateisystemen, in I/O- und CPU-Schedulern sowie Netzwerkprotokollen. eBPF-Programme können über eine (noch) rudimentäre API (Application Programming Interface) auf die Bäume zugreifen sowie Knoten hinzufügen und löschen. Diese API wird voraussichtlich in kommenden Kernel-Versionen noch ausgebaut.

Dieser direkte Zugriff auf die rbtrees aus eBPF heraus ist bemerkenswert. Bislang ließen sich komplexe Datenstrukturen aus dem Kernel lediglich als eBPF-Maps nutzen. Die eBPF-Engine im Kernel hatte weder die Privilegien noch die Notwendigkeit, komplexe Datenstrukturen im Kernel zu manipulieren.

Mit Linux 5.13 wurden bereits Kernel-Funktionen für eBPF direkt erreichbar. Damals konnte dieser Schritt noch mit dem Ziel "Vereinheitlichen" erklärt werden. Durch die Beschränkungen beim Zugriff auf Kernel-Funktionen vor 5.13 war schlicht eine Parallelwelt in eBPF entstanden, um wichtige Kernel-Funktionen dennoch nutzen zu können. Vorreiter und Sonderfall war damals die "TCP Congestion Control".

Mit dem Öffnen der rbtrees für eBPF verhält es sich jetzt anders. Normalerweise fließen derartige neue APIs nur dann ein, wenn es bereits einen konkreten Anwendungsfall im Kernel selbst gibt. Diesen gibt es diesmal jedoch nicht. Vielmehr handelt es sich um eine Weichenstellung für die Zukunft. In diesem Zusammenhang lassen die Aussagen des eBPF-Maintainers Alexei Starovoitov auf der "Linux Plumbers Conference 2022" in Dublin aufhorchen. Die Absicht hinter der Arbeit an eBPF sei, eine sicherere Version der Programmiersprache C für die Kernel-Programmierung zu schaffen.

Damit bringt sich eBPF in Stellung, zukünftig als neue und sichere Alternative Funktionen in den Kernel einzubringen. Da eBPF zudem mit seinen Hilfsfunktionen einen Bogen zwischen Userspace und Kernelspace schlägt, erinnert das nun zweifellos an eine Microkernel-Architektur durch die Hintertür.

Rust ist zwar offiziell im Kernel seit Linux 6.1 angekommen, aber auch mit den Rust-Erweiterungen in Linux 6.2 geht kaum etwas Nachvollziehbares über kleine Beispiele und Demos wie ein "Hello, world!" hinaus. Doch hinter den Kulissen geht das Klopfen und Hämmern am Rust-Grundgerüst erstaunlich schnell und praxisorientiert voran.

Ein praktischer Anwendungsfall ist ein Grafiktreiber für Apple-Hardware, den Asahi Lina in Rust programmiert und bereits im September 2022 im Entwicklerstadium zum Laufen brachte. Für den Treiber benötigt die Entwicklerin eine Reihe von Rust-Modulen, die in der Kernel-Infrastruktur noch nicht existieren. Zu Kernel 6.3 steuert sie einige Puzzle-Teile für das große Rust-Bild bei. Eines der Module der Japanerin zeigt, welche Herausforderungen die Integration von Rust im Kernel mit sich bringt.

Lina brachte unter anderem ein Modul für Zeitfunktionen ein. Im Kernel gibt es mehrere Zeitfunktionen ktime_*, die alle die Zeit im Wesentlichen als 64-Bit-Integer oder C-union diverser Integers je nach Variante in Sekunden oder Nanosekunden zurückliefern. Wie dieser Integer-Wert jedoch zu interpretieren ist, hängt von der Funktion ab, die ihn lieferte. So gibt ktime_get_boottime() die Sekunden seit dem Systemstart wieder, ktime_get_real() jedoch die Sekunden seit dem 01.01.1970 zurück, also in Epoch-/Unix-Zeit. Es ist demnach immer eine Differenz zu einem zeitlichen Fixpunkt, der variiert. Dieser Fixpunkt ist aber im zurückgelieferten Wert nirgends ersichtlich.