Hintergrund: Festplattenzugriffe über das IDE-Interface erzeugen relativ hohe CPU-Last.
Idee: IDE-Treiber nicht als Kernelmodul laden, sondern fest einkompilieren. Geht das?
Ich hab vor ein paar Jahren mal einen Uralt-PC mit Eisfair als NFS-Server für die D-Box aufgesetzt. Die Performance der Mühle stieg signifikant, nachdem ich NFS nicht mehr als Kernelmodul geladen habe, sondern NFS fest in den Kernel einkompiliert war.
IDE-Treiber fest in den Kernel einbinden?
-
- Semiprofi
- Beiträge: 1313
- Registriert: Donnerstag 2. Dezember 2004, 00:18
-
- Erleuchteter
- Beiträge: 448
- Registriert: Samstag 26. November 2005, 00:35
Intressanter Aspekt. Ganz logisch wäre es nicht wenn das immer so wäre.
Hab mal zu dem Thema Dr.Google bemüht.
Unter http://www.linuxfibel.de/kmodule.htm steht
Gruss Martin
Hab mal zu dem Thema Dr.Google bemüht.
Unter http://www.linuxfibel.de/kmodule.htm steht
Vileicht müsste man das mal wirklich verifizieren , so manches kommt ja erst beim Probieren aus.Auch die Vermutung, ein als Modul arbeitender Treiber verrichtet seine Tätigkeit weniger effizient als sein »fest angestellter Kollege«, ist falsch. Nur der erste Zugriff auf das Gerät wird, bedingt durch den jetzt anstehenden Ladevorgang, eine minimale Verzögerung mit sich bringen. Ist er einmal drin, ist kein Unterschied mehr festzustellen.
Gruss Martin
-
- Semiprofi
- Beiträge: 1313
- Registriert: Donnerstag 2. Dezember 2004, 00:18
Auf einem Pentium 133, den ich als NFS-Server laufen habe, habe ich das verifiziert.MPC823 hat geschrieben: Vileicht müsste man das mal wirklich verifizieren , so manches kommt ja erst beim Probieren aus.
NFS als Kernelmodul: 7,3 Mbit/s
NFS einkompiliert: 8,5 Mbit/s
Das war damals der Unterschied zwischen "geht gar nicht" und "läuft wie geschmiert". Wenn jemanden die alte Geschichte interessiert: http://tuxbox-forum.dreambox-fan.de/for ... hp?t=34724
-
- Semiprofi
- Beiträge: 1313
- Registriert: Donnerstag 2. Dezember 2004, 00:18
Ich hab jetzt in den letzten Stunden einigen harten Stoff zum Thema Kernelmodule gelesen. Den Treiber für das IDE-Interface hab ich mir auch angesehen, zumindest seine Schnittstellen nach außen. Grundsätzlich kann man das Ding fest einkompilieren. Die Frage ist jetzt, wie?
Bei Treibern, die zum Vanilla-Kernel gehören, ist die Sache einfach. Da geb ich einfach in der Kernelconfig an, ob ich den Treiber gar nicht, fest eingebaut oder als ladbares Modul haben will. Das Buildsystem des Kernels weiß aber nichts vom IDE-Interface der D-Box. Da wäre also Handarbeit gefragt.
Hat dazu irgend jemand sachdienliche Hinweise? O'Reillys "Linux Kernel In A Nutshell" liegt neben mir und schweigt sich zu diesem Thema aus. Die diversen Artikel zum Thema Kernelprogrammierung haben mir erklärt, wie ich ein Kernelmodul schreiben kann und anschließend dynamisch lade. Also genau das, was ich nicht wissen will.
Verdammte Hacke! Irgendwo muß geschrieben stehen, wie man so etwas statisch einbindet.
Bei Treibern, die zum Vanilla-Kernel gehören, ist die Sache einfach. Da geb ich einfach in der Kernelconfig an, ob ich den Treiber gar nicht, fest eingebaut oder als ladbares Modul haben will. Das Buildsystem des Kernels weiß aber nichts vom IDE-Interface der D-Box. Da wäre also Handarbeit gefragt.
Hat dazu irgend jemand sachdienliche Hinweise? O'Reillys "Linux Kernel In A Nutshell" liegt neben mir und schweigt sich zu diesem Thema aus. Die diversen Artikel zum Thema Kernelprogrammierung haben mir erklärt, wie ich ein Kernelmodul schreiben kann und anschließend dynamisch lade. Also genau das, was ich nicht wissen will.
Verdammte Hacke! Irgendwo muß geschrieben stehen, wie man so etwas statisch einbindet.
-
- Developer
- Beiträge: 122
- Registriert: Sonntag 23. April 2006, 12:37
Mich wundert dieser Performancegewinn bei NFS, den du da beobachtet hast. Das muß an irgendeinem Nebeneffekt liegen.
Wenn ein Kernelmodul geladen wird, wird es zum laufenden Kernel dazugelinkt. Beim statischen Einbinden wird genau das eben schon vorher durchgeführt.
Der einzige Unterschied ist, daß beim statischen Linken die Initialisierung "irgendwo" im Kernelcode stattfinden muß. Also der Aufruf der module_init()-Routine, der bei modprobe beim Laden ausgeführt wird.
Zum Einbauen, das ist nicht schwierig: guck dir den Code in drivers/ide im Kernel an. Dort sieht das dann z.B. so aus:
Die Variable $CONFIG_BLK_DEV_IDEDISK ist durch die Kernelconfig entweder "y" oder "m". Wenn sie "y" ist wird sie automatisch zum Kernel dazugelinkt, ansonsten wird daraus ein Modul.
Nur das Dazulinken reicht aber noch nicht, da wie eben beschrieben modprobe ja normalerweise noch die Initialisierung vornimmt. Das heißt, irgendwer muß nun (beim Beispiel) "idedisk_init" aufrufen.
Beim Beispielmodul findet dieser Aufruf im drivers/ide/ide.c statt. Der Aufruf ist durch ein #ifdef CONFIG_BLK_DEV_IDEDISK geschützt. Wenn man aus ide-disk ein Modul baut, dann ist die Variable nicht definiert.
Achtung: Das ist nicht die gleiche Variable, die im Shellskript verwendet wird.
An einem statischen Einbau ist daher nichts geheimnisvolles, ob es was bringt mußt du ausprobieren.
Dann muß nur noch die init-Routine irgendwo rein, gibt sicher entsprechende Aufrufe für andere IDE-Treiber, mußt du mal nach suchen.
Bei Tuxbox liegen die Treiberdateien ja in einem externen Verzeichnis, weiß gerade nicht, ob man die dort so einfach dem Kernel hinzulinken kann, ansonsten mußt du das in die Kernelsourcen reinkopieren und ein Makefile mit Config.in basteln, sollte nicht so kompliziert sein.
Ich wüßte allerdings nicht recht warum es dadurch performanter werden sollte. Aber wer weiß.
Wenn ein Kernelmodul geladen wird, wird es zum laufenden Kernel dazugelinkt. Beim statischen Einbinden wird genau das eben schon vorher durchgeführt.
Der einzige Unterschied ist, daß beim statischen Linken die Initialisierung "irgendwo" im Kernelcode stattfinden muß. Also der Aufruf der module_init()-Routine, der bei modprobe beim Laden ausgeführt wird.
Zum Einbauen, das ist nicht schwierig: guck dir den Code in drivers/ide im Kernel an. Dort sieht das dann z.B. so aus:
Code: Alles auswählen
obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
Nur das Dazulinken reicht aber noch nicht, da wie eben beschrieben modprobe ja normalerweise noch die Initialisierung vornimmt. Das heißt, irgendwer muß nun (beim Beispiel) "idedisk_init" aufrufen.
Beim Beispielmodul findet dieser Aufruf im drivers/ide/ide.c statt. Der Aufruf ist durch ein #ifdef CONFIG_BLK_DEV_IDEDISK geschützt. Wenn man aus ide-disk ein Modul baut, dann ist die Variable nicht definiert.
Achtung: Das ist nicht die gleiche Variable, die im Shellskript verwendet wird.
An einem statischen Einbau ist daher nichts geheimnisvolles, ob es was bringt mußt du ausprobieren.
Dann muß nur noch die init-Routine irgendwo rein, gibt sicher entsprechende Aufrufe für andere IDE-Treiber, mußt du mal nach suchen.
Bei Tuxbox liegen die Treiberdateien ja in einem externen Verzeichnis, weiß gerade nicht, ob man die dort so einfach dem Kernel hinzulinken kann, ansonsten mußt du das in die Kernelsourcen reinkopieren und ein Makefile mit Config.in basteln, sollte nicht so kompliziert sein.
Ich wüßte allerdings nicht recht warum es dadurch performanter werden sollte. Aber wer weiß.
-
- Semiprofi
- Beiträge: 1313
- Registriert: Donnerstag 2. Dezember 2004, 00:18
Ich zitier mal was:Carjay hat geschrieben:Mich wundert dieser Performancegewinn bei NFS, den du da beobachtet hast. Das muß an irgendeinem Nebeneffekt liegen.
Quelle: Welsh, Dalheimer, Dawson, Kaufman; Linux Praxishandbuch; O'Reilly Verlag; 4.Auflage 2003; ISBN 3-89721-416-4; S. 253"Ein monolithischer Aufbau verbessert gegenüber einem Mikro-Kernel die Leistung (heutzutage liegt der Unterschied zwischen monolithischen Kerneln und Mikro-Kerneln unter 5%).
Mit heutzutage meinen die Autoren PC-Prozessoren von 2002/2003, die alle geringfügig performanter sind, als unser kleiner Power-PC.
Beim Thema "dynamisches Linken" bin ich nicht ganz sattelfest, aber ich meine mich zu erinnern, daß das ein paar Klimmzüge erfordert, weil die Einsprungadressen der Funktionen eben nicht durch den Linker fest verdrahtet werden, sondern der Umweg über eine Tabelle gemacht werden muß.Wenn ein Kernelmodul geladen wird, wird es zum laufenden Kernel dazugelinkt. Beim statischen Einbinden wird genau das eben schon vorher durchgeführt.
Vielen Dank übrigens für die anderen Ausführungen. Mitlerweile habe ich selber schon einiges an Infos zum Kernelbau gefunden, zwar nicht im Netz, dafür aber auf meiner Festplatte im Kernel-Source-Tree.
Sicher? Ich dachte, genau dafür wären die Makros aus modules.h da. Die dienen eigentlich dazu, daß der gleiche Code als Modul oder fester Kernelbestandteil funktioniert.Nur das Dazulinken reicht aber noch nicht, da wie eben beschrieben modprobe ja normalerweise noch die Initialisierung vornimmt. Das heißt, irgendwer muß nun (beim Beispiel) "idedisk_init" aufrufen.
Da liegt der Hund begraben, zumindest einer. Beim Bauen des CVS werden Kernel und die speziellen Module für die D-Box unabhängig voneinander gebaut. Das Buildsystem des Kernels weiß nix von der D-Box. Muß es aber, wenn es D-Box-Treiber in den Kernel integrieren soll.Bei Tuxbox liegen die Treiberdateien ja in einem externen Verzeichnis,
Darauf wird es für einen Schnell-und-schmutzig-Test hinauslaufen. Zum Ausprobieren reicht das ja.ansonsten mußt du das in die Kernelsourcen reinkopieren und ein Makefile mit Config.in basteln,
-
- Developer
- Beiträge: 122
- Registriert: Sonntag 23. April 2006, 12:37
Das Zitat bezieht sich auf ein theoretisches Konzept. Der Linux-Kernel ist kein Mikro-Kernel, keines der bekannten OS ist das, aus genau dem Grund, den das Zitat anführt. Bei einem Mikro-Kernel laufen zum Beispiel die Gerätetreiber im Userspace.wolgade hat geschrieben: Ich zitier mal was:"Ein monolithischer Aufbau verbessert gegenüber einem Mikro-Kernel die Leistung (heutzutage liegt der Unterschied zwischen monolithischen Kerneln und Mikro-Kerneln unter 5%).
Der Linux-Kernel ist ein monolithischer Kernel. Der Windows NT-Kernel ist das übrigens nicht (er ist eine Mischung aus beiden, manchmal auch Hybrid-Kernel genannt, weil z.B. das Win32-Subsystem im Userspace läuft)
Müßte genau nachschauen aber ich denke nicht, daß der generierte Objektcode sich groß unterscheidet zwischen statisch eingelinktem Code und Kernelmodul. Das Kernelmodul ist ja keine dynamische Bibliothek, die gemeinsam von verschiedenen Programmen benutzt werden soll.Beim Thema "dynamisches Linken" bin ich nicht ganz sattelfest, aber ich meine mich zu erinnern, daß das ein paar Klimmzüge erfordert, weil die Einsprungadressen der Funktionen eben nicht durch den Linker fest verdrahtet werden, sondern der Umweg über eine Tabelle gemacht werden muß.
Stimmt, es gibt da wohl noch die Möglichkeit der Initialisierung über das Initcall-Segment. Das passiert aber scheinbar in der Reihenfolge des Linkens und ist vielleicht nicht immer das was man will.Sicher? Ich dachte, genau dafür wären die Makros aus modules.h da. Die dienen eigentlich dazu, daß der gleiche Code als Modul oder fester Kernelbestandteil funktioniert.
-
- Semiprofi
- Beiträge: 1313
- Registriert: Donnerstag 2. Dezember 2004, 00:18
Weiß ich, Ich kenne auch den legendären Schlagabtausch zwischen Linus Torvalds und Andrew Tannenbaum.Carjay hat geschrieben:Der Linux-Kernel ist kein Mikro-Kernel,
Der von mir zitierte Satz steht in dem Buch aber in dem Kontext "Kernelmodul vs. fest einkompiliert". So ganz monolithisch ist ein modularisierter Linux-Kernel ja auch nicht mehr.
Wir müssen aber auch gar keine theoretische Debatte über Betriebssysteme führen. Davon verstehe ich viel zu wenig. Außerdem wird es nicht die Frage beantworten, ob mein Ansatz nun etwas bringt oder nicht. Das muß ich einfach ausprobieren. Versuch macht klug.
Gut, dann habe ich den Abschnitt aus der Kerneldoku richtig verstanden. Danke.Stimmt, es gibt da wohl noch die Möglichkeit der Initialisierung über das Initcall-Segment. Das passiert aber scheinbar in der Reihenfolge des Linkens und ist vielleicht nicht immer das was man will.