Open Source im professionellen Einsatz

Kernel- und Treiberprogrammierung mit dem Kernel 2.6 - Folge 19

Kern-Technik

,

Bei Linux 2.6.10 kann der Anwender über die Auswahl von IO-Schedulern bestimmen, wie der Kernel auf Festplatten zugreift. Wer weiß, wie sie intern funktionieren, passt das System optimal an die eigene Anwendung an. Zur Laufzeit lassen sich die IO-Scheduler über das SysFS austauschen und einstellen.

Das Blockgeräte-Subsystem - im Kernel 2.6 grunderneuert - ist für den effizienten Transport von Daten zwischen Applikationen und Festplatten verantwortlich[1]. Damit hat es wesentlichen Anteil an der Performance und an der so genannten Interaktivität des Systems. Eine ganze Reihe von Techniken gestaltet den Zugriff möglichst optimal (siehe Abbildung 1).

Getrennt lesen und schreiben

So trennt der VFS (Virtual Filesystem Switch) die Aufträge für zeichenorientierte Geräte von denen für blockorientierte. Außerdem löst er Dateinamen in Sektornummern auf. Die zu einer Sektornummer gehörigen Daten sucht der Kernel im Page-Cache, der die Applikation von dem eigentlichen Gerät entkoppelt. Für diese Aufgabe hält der Page- Cache jeweils eine Kopie genau jenes Blocks (Sektors) vorrätig, auf den die Applikation zugreifen möchte. Der Page-Cache legt die Kopie dabei asynchron zum Ablauf der Applikation an.

Die im Page-Cache generierten Aufträge (Requests) werden dem so genannten Elevator übergeben, der das Zusammenfassen und Sortieren von Aufträgen im IO-Scheduler veranlasst. Darüber hinaus sorgt der Elevator (Fahrstuhl) dafür, dass sich der Gerätetreiber zu gegebener Zeit seine Aufträge abholt. Allerdings tut er dies erst dann, wenn eine ausreichende Anzahl von Aufträgen vorhanden ist - sonst gibt es schließlich nichts zu sortieren (siehe Kasten "IO-Scheduler im Blockgeräte-Subsystem").

Verstopfen und füllen

Bildlich gesprochen verschließt (Plugging) der Elevator den Pool (Queue), in dem sich die Aufträge befinden und zum Sortieren ansammeln. Dann entfernt der Scheduler den Stopfen (Unplugging) und reicht die Aufträge an den Treiber weiter. Natürlich darf der Pool nicht zu lange zugepfropft bleiben. Deshalb startet man beim ersten Auftrag einen Timer mit einem Wert von beispielsweise drei Millisekunden.

Das Sortieren und Zusammenfassen der Aufträge beschleunigt den Festplattenzugriff insgesamt, denn diese Strategie minimiert Bewegungen des Schreib-Lese- Kopfes. Das deutet bereits der Name Elevator an: Die Aufträge werden nach Möglichkeit so an die Platte weitergereicht, dass der Schreib-Lese-Kopf der Platte keine Zickzack-Bewegungen ausführen muss, sondern sich fahrstuhlähnlich von den niedrigen Sektornummern zu den hohen bewegt und genauso wieder wieder zurück.

So einfach das Prinzip klingt, so kompliziert ist es zu implementieren. Ein einfaches Einsortieren neuer Aufträge führt nämlich unter ungünstigen Umständen zum Verhungern (Starvation) einzelner Requests. Erteilt eine Applikation beispielsweise den Auftrag, die Sektoren mit den Nummern 20 und 30000 zu lesen, wird der Block 30000 eventuell erst zu einem viel späteren Zeitpunkt gelesen. Das wäre der Fall, wenn andere Applikationen nur Sektoren kleiner 30000 anfordern.

Das Einsortieren der Aufträge steigert zwar die IO-Performance, verschlechtert aber die Interaktivität. Hier gilt es also, einen möglichst guten Kompromiss zu finden. Dass dieser möglichst wenig Rechenleistung verbrauchen soll, versteht sich von selbst. Da es keinen für jede Anwendung optimalen IO-Scheduler gibt, stellt Kernel 2.6 vier verschiedene Algorithmen zur Wahl: No-Op-, Deadline-, Anticipatory- und CFQ-IO-Scheduler (siehe Abbildung 2).

Der No-Op-Scheduler ist in jedem Fall im Kernel einkompiliert, schon um beim Booten auf das Root-Filesystem zugreifen zu können. Der User darf beim Kernel-Compile auch mehrere IO-Scheduler konfigurieren und beim Booten einen davon auswählen. Noch besser ist allerdings: Ab Kernel 2.6.10 lässt sich der IO-Scheduler für jedes Blockgerät jederzeit separat auswählen. Entsprechende Einträge im Sys-Filesystem passen den Algorithmus optimal an die eigene Anwendung an (siehe Kasten: "IO-Scheduler im Kernel 2.6.10").

Abbildung 1: Verschiedene Mechanismen beschleunigen den Zugriff auf langsame Festplatten. Die Funktionen »elv_add_request_fn()« und »elevator_next_req()« sind die Hauptschnittstellen zum IO-Scheduler.

Abbildung 1: Verschiedene Mechanismen beschleunigen den Zugriff auf langsame Festplatten. Die Funktionen »elv_add_request_fn()« und »elevator_next_req()« sind die Hauptschnittstellen zum IO-Scheduler.

Abbildung 2: Auswahl der IO-Scheduler bei der Kernelkonfiguration. Sind alternative IO-Scheduler Teil des Kernels, kann der Benutzer sie zur Laufzeit über das Sys-Filesystem austauschen.

Abbildung 2: Auswahl der IO-Scheduler bei der Kernelkonfiguration. Sind alternative IO-Scheduler Teil des Kernels, kann der Benutzer sie zur Laufzeit über das Sys-Filesystem austauschen.

Diesen Artikel als PDF kaufen

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook