Lowlevel

Lowlevel => OS-Design => Thema gestartet von: FlashBurn am 23. November 2011, 16:29

Titel: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 16:29
Ich will ja die Idee von erik benutzen, wo der IPC-Handler in einem eigenen Thread läuft. Dieser Thread wird auch wirklich erst erstellt wenn eine Nachricht vorhanden ist/empfangen wird.

Dabei ist halt ein Problem bei meinem Kernel-Design aufgetreten. Dort ist es nicht möglich auf den VMM eines anderen Prozesses zu zugreifen, was ja nötig wäre um einen Stack für den Thread erstellen zu können.

Der Grund warum das nicht möglich ist, ist folgender. Auch der VMM braucht ja Speicher um die freien Bereiche verwalten zu können. Allerdings kann er ja schlecht die normalen malloc()/free() Funktionen nutzen, weil die wiederrum auf den VMM aufbauen.
Deswegen habe ich im KernelSpace einen Prozess-lokalen Bereich (der ist immer an der gleichen virtuellen Adresse) wo nur ein "kleiner" Speicher-Manager läuft und auch genau auf den VMM zugeschnitten ist.
Es ist halt einfacher wenn ich nur einen festen Bereich verwalten muss, als wenn ich das ganze von der Größe her dynamisch machen müsste.

Ich habe auch schon eine Idee für eine Lösung.

Wenn ein Client eine RPC-Anfrage macht, muss er in den Kernel. Dort wird dann der fixed-size Anteil der Message in einen Kernel-Buffer kopiert (sind im Mom 32bytes, die man als Metadaten nutzen könnte).
Es wird dann geguckt ob ein neuer Thread beim Empfänger erstellt werden darf (man kann bei der Erstellung der Ports festlegen wieviele Threads max gestartet werden dürfen), ist das der Fall so wird einfach in das PD des Empfängers gewechselt, ein neuer Thread erstellt und dieser wird gleich gestartet ohne das der Scheduler davon wissen muss.

Ist der Handler fertig (die Funktion macht also nen "ret" was wiederrum bewirkt das zurück in den Kernel gesprungen wird) wird überprüft ob eine weitere Nachricht vorliegt oder ob der Thread beendet werden kann.
Liegt eine weitere Nachricht vor, wird diese bearbeitet und der Sender-Thread wird in die Ready-Queue des Schedulers gepackt. Kann der Thread beendet werden, wird danach gleich in das PD des Senders gewechselt und der Sender Thread wird laufen gelassen.

Wird nur eine Nachricht versendet ohne das gewartet werden soll (oder es keine Antwort gibt), so muss trotzdem in das PD des Empfängers gewechselt werden und es wird ein neuer Thread erstellt. Dieser wird dann in die Ready-Queue des Schedulers gepackt und es wird wieder zurück in das PD des Senders gewechselt.

Falls jemand eine gute Idee hat, wie ich das Wechseln der PDs vermeiden kann, also im Endeffekt wie ich den Speicher für den VMM verwalten kann, dann immer her damit.

Fallen euch daran irgendwelche groben Fehler auf oder habt ihr eine bessere Idee (die Popup-Threads bleiben ;))?
Titel: Re: IPC - Popup-Threads
Beitrag von: kevin am 23. November 2011, 16:42
Deine Speicherverwaltung ist komisch.

Warum kann sich der VMM nicht einfach den Speicher nehmen, den er selber braucht? Wie man physischen Speicher holt, dürfte er wissen, und wie man ihn mappt auch.
Titel: Re: IPC - Popup-Threads
Beitrag von: Jidder am 23. November 2011, 16:47
Ich würde den Stack erst erstellen, wenn der Scheduler zum Thread wechselt. Zum Beispiel durch einen Stub, der vor dem Sprung in den User-Space ausgeführt wird.

Ansonsten der übliche Trick: Wenn du das Page Directory des anderen Prozesses in das Page Directory des aktuellen Prozesses als Page Table einträgst, kannst du darauf als 4 MB kontinuierlichen Speicher zugreifen.
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 16:59
Zitat von: taljeth
Warum kann sich der VMM nicht einfach den Speicher nehmen, den er selber braucht? Wie man physischen Speicher holt, dürfte er wissen, und wie man ihn mappt auch.
Und wo soll er den hinmappen? Ich hatte es vor langer Zeit auch mal so, dass der VMM ganz normal seine Objekte alloziert hat, aber das führt zu so vielen Problemen und Code der manchmal funktioniert und manchmal nicht.

Es geht doch bei einem VMM darum, das er weiß welche Bereiche im virtuellem Speicher frei sind und welche nicht und dafür braucht er Speicher. Mein VMM besteht im wesentlichen aus 2 AVL-Bäumen, einen der die Bereiche nach der Größe sortiert und einer der die Bereiche nach der Start-Adresse sortiert.

Allerdings kommt mir gerade eine Idee (wo ich mich wieder frage wieso ich die nicht schon eher hatte) und zwar reicht es ja, wenn der Kernel-VMM so gebaut ist. Der User-VMM kann dann die allgemeinen Speicherfunktionen nutzen.
Das würde sogar sehr einfach umzusetzen sein, würde aber zu einem anderen Problem führen (was nicht unbedingt auftreten muss, aber kann). Jetzt ist es so, dass wenn ein Prozess beendet wird, wird auch der gesamte Speicher, den der VMM gebraucht hat, freigegeben. Bei der obigen Variante kann es (und wird es bestimmt auch) aber passieren, das die Objekte so dämlich über viele Objekt-Caches (SlabAllocator) verteilt sind, das man nacher eine Aufteilung, das jeder Objekt-Cache im worst-case genau ein Objekt hat, welches noch in Benutzung ist und es deswegen zu einer tierischen Speicherverschwendung kommt (pro Objekt in dem Fall etwas über 4000bytes, macht bei einem Prozess mit 1024 freien Bereichen schonmal 4MB verschwendet).

Ist halt die Frage, was ist wichtiger Speicherverbrauch oder Performanceeinbußen wegen dem Wechseln des PDs.

Zitat von: jidder
Ich würde den Stack erst erstellen, wenn der Scheduler zum Thread wechselt. Zum Beispiel durch einen Stub, der vor dem Sprung in den User-Space ausgeführt wird.
Finde ich ne ganz schlechte Idee, weil erst dann festgestellt werden kann ob genügend Speicher für den Stack vorhanden ist oder nicht und Fehler, vorallem solche, will ich im Scheduler gar nicht haben.
Titel: Re: IPC - Popup-Threads
Beitrag von: kevin am 23. November 2011, 17:14
Und wo soll er den hinmappen? Ich hatte es vor langer Zeit auch mal so, dass der VMM ganz normal seine Objekte alloziert hat, aber das führt zu so vielen Problemen und Code der manchmal funktioniert und manchmal nicht.
Ich dachte, im eigenen Prozess (und vor allem im Kernelspeicher, der ja in allen Prozessen der gleiche ist) kann der VMM allozieren und das Problem ist nur mit anderen Prozessen? Seinen Verwaltungskram braucht der VMM ja nicht im Userspeicher anderer Prozesse, sondern im sowieso aktiven Kontext.
Titel: Re: IPC - Popup-Threads
Beitrag von: Jidder am 23. November 2011, 17:17
Finde ich ne ganz schlechte Idee, weil erst dann festgestellt werden kann ob genügend Speicher für den Stack vorhanden ist oder nicht und Fehler, vorallem solche, will ich im Scheduler gar nicht haben.

Achso jetzt verstehe ich. Es geht eigentlich gar nicht um das Page Directory, sondern darum, dass du auf den virtuellen Adressraum des anderen Prozesses zugreifen willst.

Da du vor nichts zurückschreckst, will ich dann mal noch eine abenteuerliche Lösung vorschlagen. Du könntest ausnutzen, dass dein VMM für jeden Prozess in einem begrenzten Bereich liegt. Dann kannst du einfach die dazugehörigen Einträge im PD des Sender mit den Werten aus dem PD des Empfängers überschreiben, den Speicher normal reservieren, und anschließend die alten Werte wiederherstellen. Mit etwas Glück gibt es nicht mal unnötige TLB-Misses, falls das die einzigen Zugriffe auf den VMM sind.
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 17:31
Zitat von: taljeth
Ich dachte, im eigenen Prozess (und vor allem im Kernelspeicher, der ja in allen Prozessen der gleiche ist) kann der VMM allozieren und das Problem ist nur mit anderen Prozessen?
Jap, es geht darum, das ich aus einem Prozess heraus nicht auf den VMM eines anderes Prozesses zugreifen kann. Der Kernel hat aber auch nen VMM der irgendwo her seinen Speicher bekommen muss und der ist auch in alle Prozesse gemappt.

Zitat von: jidder
Achso jetzt verstehe ich. Es geht eigentlich gar nicht um das Page Directory, sondern darum, dass du auf den virtuellen Adressraum des anderen Prozesses zugreifen willst.
Auch darum geht es nicht ganz ;) Ich müsste auf den VMM eines anderen Prozesses zugreifen und der VMM für jeden Prozess holt sich den Speicher für seine Objekte immer aus dem selben virtuellen Bereich.

Zitat von: jidder
Du könntest ausnutzen, dass dein VMM für jeden Prozess in einem begrenzten Bereich liegt. Dann kannst du einfach die dazugehörigen Einträge im PD des Sender mit den Werten aus dem PD des Empfängers überschreiben, den Speicher normal reservieren, und anschließend die alten Werte wiederherstellen. Mit etwas Glück gibt es nicht mal unnötige TLB-Misses, falls das die einzigen Zugriffe auf den VMM sind.
Ansich gar keine schlechte Idee, aber ... ;)

Was machst du bei Multithreading? Thread A mappt also den VMM raus und den von einem anderen Prozess rein und Thread B will jetzt, auf einer anderen CPU, gleichzeitig Speicher anfordern!

Also mein VMM besteht aus 2 AVL-Bäumen, dort werden Nodes gespeichert (erster Objekttyp) und dann gibt es die Bereiche (zweiter Objekttyp). Für diese beiden Objekttypen muss ich ja irgendwo her Speicher bekommen.
Wenn der VMM also nen neuen freien Bereich eintragen will, muss er eventuell zwei neue Nodes und einen neuen Bereich allozieren. Wenn er dabei ganz normal ein malloc() aufrufen würde, würde das malloc() feststellen das es neuen Speicher braucht und den VMM aufrufen ...

Ich hoffe das Problem ist klar.

Ich habe das ganze so gelöst das ich einen festen virtuellen Bereich habe wo ein "einfacher" Allocator Speicher für diese beiden Objekttypen herholt (er braucht keinen dynamischen Speicher dafür, weil die Größe und Position des Bereichs ja statisch schon zur Compilezeit bekannt ist). Das ganze habe ich einmal für den Kernel-VMM (und dieser Bereich ist in jedem Adressraum der gleiche) und einmal für den User-VMM (dieser Bereich ist in jedem Adressraum mit anderen Daten/Pages gemappt).

Ich kann also für einen Prozess der gerade die CPU hat, ganz einfach Speicher über den VMM allozieren, aber wenn ich aus einem Prozess A heraus Speicher in einem Prozess B allozieren will, muss ich auf dessen VMM zugreifen. Das bringt Probleme, weil der VMM von Prozess B Objekte benutzt die an der selben Adresse liegen wie Objekte vom Prozess A. Dadurch kann ich den VMM des Prozesses B auch nicht einfach in Prozess A mappen (zumal das eh Probleme bei vielen CPUs gibt, da irgendwann auch der virtuelle Speicher ausgeht).
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 23. November 2011, 17:40
Hallo,


@FlashBurn: was genau versuchst Du mit Deiner komplizierten VMM-Architektur eigentlich zu erreichen? Der Vorteil den Du momentan hast ist wohl der das Deine beiden Bäume immer an der selben virtuellen Adresse anfangen können (da sie ja im privaten Adressraum der entsprechenden Prozesse liegen, auch wenn dieser Bereich nicht mit Ring 3 ansprechbar ist) wohingegen wenn alle Bäume ganz normal im Kernel-Kontext liegen hat jeder Prozess individuelle virtuelle Baum-Adressen. Zwei zusätzliche Pointer in der Prozess-Descriptor-Struktur machen aber IMHO keine ernsten Probleme so das ich trotz allem dafür bin das die Prozess-spezifischen VMM-Daten im normalen Kernel-Speicher liegen und der VMM eben immer als zusätzliches Parameter den Pointer für den gewünschten Prozess bekommt damit der VMM auch immer für den richtigen Prozess arbeitet. Der VMM benötigt dann für sich selber (neben dem PMM für den eigentlichen Speicher der in den Prozess gemappt werden soll) wieder den Allocator des Kernels (der nur für den Kernel-Speicher zuständig ist und welcher für sich ebenfalls den PMM benötigt).

Da diese IPC-Idee ursprünglich für meine segmentierte Speicherverwaltung erdacht wurde, in der der Kernel immer alles sieht (es gibt ja auch nur maximal ein PD), hab ich damit bis jetzt kein Problem gesehen wenn der Kernel für einen beliebigen Prozess Threads in einem anderen beliebigen Prozess erstellt. Ich bin auch der Meinung das selbst bei Flat-Memory keine grundsätzlichen Probleme im Weg stehen.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 18:00
Zitat von: erik
was genau versuchst Du mit Deiner komplizierten VMM-Architektur eigentlich zu erreichen?
Ich habe doch das Problem beschrieben das der Kernel-VMM auch Speicher für seine eigenen Objekte braucht und normalerweise malloc() dafür aufrufen würde. Malloc() wiederrum ruft dann den Kernel-VMM zwecks neuem Speicher auf. Das kann nicht funktionieren und man muss also nen "einfachen" Speichermanager zumindest für die Objekte des VMM haben.

Ich nutze halt den selben Code für den Kernel- und die User-VMMs.

Ich könnte, wie oben schon geschrieben, auch einfach nur den Kernel-VMM diesen "einfachen" Speichermanager nutzen lassen und die User-VMMs nutzen dann ganz normal Kernel-Speicher. Das wiederrum hätte aber einen Nachteil was den eventuellen Speicheroverhead betrifft, wäre aber performanter.

Nur bin ich mir halt nicht sicher, ob der Performanceunterschied wirklich relevant ist. Denn die einzige Situation (die mir im Moment einfällt), wo ich auf den VMM eines anderen Prozesses zugreifen muss, ist IPC.
Wenn ich jetzt davon ausgehe, dass nur beim RPC auch auf den VMM eines anderen Prozesses zugegriffen werden muss (und das nur beim Senden, für die Antwort ja nicht) und ich dann auch gleich in dem anderen Prozess bleibe, habe ich eigentlichen keinen Performance-Vor- oder -Nachteil.

Ausnahme wäre da jetzt nur asynchrones-IPC, aber da fallen mir im Moment auch nur Notify-Nachrichten ein und dafür würden meine fixed-size-Nachrichten eigentlich ausreichen und da würde dann also auch nicht auf den VMM eines anderen Prozesses zugegriffen.

Meine Frage wäre dann, wie löst ihr das, dass der Kernel-VMM ja auch irgendwo Speicher herbekommen muss?
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 23. November 2011, 20:09
Hallo,


@FlashBurn: ich schätze Du hast ein paar ungünstige Abhängigkeiten in den Schichten Deiner Speicherverwaltung drin.

Für ein Flat-Memory-System würde ich das etwa so konstruieren:

User-Mode-Library (libc) bietet malloc()/free() für beliebig große Speicherblöcke für den User-Mode-Code und benutzt dazu den virtuellen Adressraum das Prozess
wenn da neue Pages her müssen oder welche frei gegeben werden können dann wird der Prozess-spezifische VMM im Kernel per Syscall aufgerufen
    |
   V
der Prozess-spezifische VMM wird vom User-Mode oder von verschiedenen Kernel-internen Funktionen aufgerufen wenn in den virtuellen Adressraum eines Prozess (also das was pro Prozess individuell ist) etwas gemacht werden soll
er holt sich die eigentlichen Speicherseiten direkt beim PMM und seine Verwaltungsstrukturen beim Kernel-VMM
    |
   V
der Kernel-VMM bietet quasi das malloc()/free() für alles innerhalb des Kernels (bei einem Micro-Kernel wo nur wenige Objekt-Größen erforderlich sind kann das direkt von einem optimierten SLAB-Allocator erledigt werden und bei einem Monolithen wird man wohl eher was generisches benötigen das der libc-Variante im User-Mode recht ähnlich ist) und ist nur für den virtuellen Adressraum des Kernel zuständig (also den Teil des virtuellen Adressraum der in allen PDs identisch ist, ein vom Kernel-VMM gelieferter Pointer ist demzufolge in allen Kontexten gültig)
der Kernel-VMM greift für alles was er braucht auf den PMM zurück
    |
   V
der PMM ist die unterste Stufe und sollte im Idealfall keine Abhängigkeiten zu was anderem haben dafür kann er nur ganze Pages verwalten
theoretisch könnte der PMM für seine Verwaltungsstrukturen wieder auf den Kernel-VMM zurückgreifen aber das ist dann eine Kreisabhängigkeit die man nicht so ohne weiteres problemfrei bekommt und sollte fürs erste vermieden werden

Ich hoffe das hilft etwas und ist nicht zu arg falsch.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 20:27
@erik

Das ist mir auch alles klar und sieht auch so ähnlich bei mir aus. Ich habe nur noch eine Schicht zw. SlabAllocator und PMM, nämlich den VMM.

Auch dein Bsp. sagt mir nicht woher der SlabAllocator weiß welche virtuellen Adressen frei und welche belegt sind. Das muss du doch irgendwie verwalten und dafür brauchst du Speicher.

Der SlabAllocator funktioniert doch so, das er guckt ob er einen komplett freien ObjectCache oder einen ObjectCache mit mind. einem freien Objekt hat. Ist das nicht der Fall fragt er den VMM nach sovielen Pages wie man pro ObjectCache für den entsprechenden Objekttypen braucht.
Der VMM benutzt nun praktisch den SlabAllocator für die Objekte die er zur Verwaltung des virtuellen Speichers braucht. Da haben wir dann wieder diese Abhängigkeit die sich nicht so einfach auflösen lässt. Dafür brauchst du einen Allocator der keinen dynamischen Speicher braucht bzw. diesen irgendwo herbekommt ohne einen anderen Speichermanager aufzurufen.

Um es kurz zu machen, woher weiß, in deinem Bsp., der SlabAllocator wo noch freie Bereiche im Adressraum des Kernels sind? Das steht in einer Datenstruktur und wo kommt der Speicher (der ja auch dynamisch verwaltet werden soll) für diesen Speicher her?

Ich möchte meinen aus diesem Grund nutzt man unter Linux nen BuddyAllocator und hat das Prinzip des HighMem. Man nutzt also im Kernel ein 1:1 Mapping der physischen und virtuellen Adressen. Das ist aber mMn totaler Müll, ist zwar einfach aber du bekommst dadurch Probleme wo ich ehrlich gesagt nur drüber lachen kann ;) Aber du kannst dir den VMM für den Kernel sparen.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 23. November 2011, 21:23
Hallo,


die libc holt sich den Speicher für die eigenen Verwaltungsstrukturen natürlich auch vom Prozess-spezifischen VMM aus dem Kernel, diese Verwaltungsstrukturen beschreiben nicht nur den virtuellen Adressraum (des Prozesses) aus Sicht der libc sondern auch sich selber. Genauso machen das auch die beiden VMMs im Kernel, die Verwaltungsstrukturen beschrieben nicht nur den Speicher der eigentlich verwaltet werden soll sondern auch immer sich selber. Die SLAB-Blöcke enthalten im jeweiligen Header immer Pointer auf andere SLAB-Blöcke (so das daraus eine Liste aus SLAB-Blöcken entsteht, diese Liste könnte z.B. nach der Anzahl der verfügbaren/freien Objekte im entsprechenden Block sortiert sein). Der SLAB-Allocator muss auch nicht wissen wo noch freie virtuelle Pages vorhanden sind, wenn er ein neues Objekt liefern soll aber in seiner SLAB-Block-Liste keines mehr zu finden ist dann fordert er einfach eine/mehrere neue Seite(n) (dazu muss er natürlich in dem selber verwalteten virtuellen Adressraum ein freies Plätzchen suchen) vom PMM an und baut daraus einen neuen SLAB-Block für die gewünschte Objekt-Größe und bindet diesen neuen Block in die entsprechende Liste mit ein. Die einzigste Speicherverwaltung die wirklich nicht auf anderes angewiesen sein sollte ist der PMM und da die Menge des physischen Speichers ja zur Kernel-Lade-Zeit bekannt ist (und sich auch nur selten zur Laufzeit ändert, zumindest ist das noch kein Aspekt für die erste OS-Version) kann hier auch mit einer statischen Methode (z.B. simple Bit-Map) gearbeitet werden.

@FlashBurn: Ich kann ehrlich gesagt nicht erkennen wo Du genau das Problem siehst. Vielleicht sollte ich wirklich mal ein Flat-Memory-OS bauen um zu verstehen wo da noch versteckte Probleme sein könnten. ;)
So ähnlich wie ich das vorhin skizziert habe möchte ich das auch für meine segmentierte Speicherverwaltung bauen, nur eben mit der Kreisabhängigkeit zwischen PMM und Kernel-VMM.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 23. November 2011, 21:36
Zitat von: erik
Der SLAB-Allocator muss auch nicht wissen wo noch freie virtuelle Pages vorhanden sind, wenn er ein neues Objekt liefern soll aber in seiner SLAB-Block-Liste keines mehr zu finden ist dann fordert er einfach eine/mehrere neue Seite(n) (dazu muss er natürlich in dem selber verwalteten virtuellen Adressraum ein freies Plätzchen suchen) vom PMM an und baut daraus einen neuen SLAB-Block für die gewünschte Objekt-Größe und bindet diesen neuen Block in die entsprechende Liste mit ein.
Wenn der SlabAllocator nicht weiß wo nach freie virtuelle Pages/Adressen sind, woher weiß er dann wo er die physischen Pages hinmappen soll?

Also ich holle mir ne Page vom PMM (Pmm::alloc4kb()) und dann muss ich diese mappen (Vmm::map(virt,phys,count,flags)), aber woher weiß ich wo noch ne freie virtuelle Adresse ist?

Du sprichst von einem selber verwalteten virtuellem Adressraum. Wie willst du den verwalten? Ich mache das, wie schon öfter geschrieben, mit 2 AVL Bäumen und für die Nodes und die eigentlichen Objekte die die Bereiche beschreiben, brauche ich Speicher und auch der wird ja dynamisch verwaltet.

Einfach mal als Bsp., folgende Adressen sind noch frei 0xC4000000 bis 0xC5000000 und 0xD0000000 bis 0xE0000000. Woher weißt du das die noch frei sind und wo speicherst du diese Information?

Ich weiß das du die Infos direkt in deinen Segmenten speichern kannst und daraus ne Liste machen kannst, das geht hier aber nicht. Vorallem weil ich kein 1:1 Mapping will und weil der KernelSpace "nur" 1GB groß ist und damit kann ich nicht einfach auf die vollen 4GB zugreifen.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 24. November 2011, 15:44
Hallo,


schau Dir mal an wie verschiedene libc-Implementierungen das lösen. Das malloc()/free() kann ja auch nicht für jede Page den Kernel fragen ob es die benutzen kann oder nicht. Dort werden ein paar statische Variablen (Pointer und Größenangaben) benötigt die quasi den Einstiegspunkt die die Heap-Verwaltung ermöglichen und alles andere ist weitgehendst dynamisch. Mit den statischen Variablen wird z.B. beschrieben in welchem Teil des linearen Adressraums der Heap liegt (falls das mehrere sein können wird es natürlich etwas komplexer) und die Pointer zeigen dann auf die Verwaltungsstrukturen die zwischen den User-Blöcken ebenfalls im Heap liegen. Diese Verwaltungsstrukturen beschreiben welche Bereiche im Heap benutzt und welche frei sind, dabei zählen die Verwaltungsstrukturen selber ebenfalls als benutzter Speicher. Das bedeutet das in dem Moment wo die Heap-Verwaltung initialisiert wird (und der erste Bereich im virtuellen Adressraum mit Hilfe des Kernels für den Heap reserviert wird) das dann ein kleiner Teil dieses ersten Bereiches sofort mit den ersten paar Elementen der Verwaltungsstrukturen belegt wird (diese ersten Verwaltungsstrukturen beschreiben sich selber und auch den noch freien Rest).
Es ist sogar möglich mehrere unabhängige Heap-Verwaltungen parallel in einem Prozess zu betreiben (es muss nur jede einen eigenen Satz an statischen Variablen haben), die kommen sich auch nie in die Quere weil ja jede Heap-Verwaltung individuelle Bereiche des virtuellen Adressraums vom Kernel bekommt. Es sieht auch keine dieser Heap-Verwaltungen den Speicher der anderen Heaps. Theoretisch können diese Heap-Verwaltungen sich sogar gegenseitig benutzen, das würde z.B. dann Sinn ergeben wenn eine Heap-Verwaltung eine andere Benutzt um mit deren Hilfe ihre eigenen Verwaltungsstrukturen zu verwalten (in dem Fall würden im ersten Heap tatsächlich nur die User-Blöcke liegen und die zugehörigen Verwaltungsstrukturen in einem anderen Heap).
Damit die Verwaltungsstrukturen zusätzlich zu den User-Blöcken auch sich selber beschreiben können müssen die eine hohe Effizienz haben (es müssen also als Anzahl weniger Verwaltungsstrukturen benötigt werden als User-Blöcke und Verwaltungsstrukturen vorhanden sind). Wenn man die Verwaltungsstrukturen immer als Header vor jeden User-Block legt ergibt sich ein 1:1-Verhältnis und wenn man die Verwaltungsstrukturen als eigenständigen Baum verwalten will ist man fast zwangsläufig auf einen SLAB-Allocator angewiesen (die Verwaltungsstrukturen beschreiben dann nur die User-Blöcke (pro User-Block eine Verwaltungsstruktur bzw. Baum-Node) und die Slab-Blöcke (pro SLAB-Block eine Verwaltungsstruktur aber jeder SLAB-Block bietet ja Platz für mehrere Verwaltungsstrukturen)).

Der Prozess-spezifische VMM im Kernel verwaltet den jeweiligen virtuellen Adressraum der Prozesse aber die dafür benötigten Verwaltungsstrukturen (Deine Baum-Nodes) holt er sich per kmalloc()/kfree() vom Kernel-VMM (so das diese nicht innerhalb des Prozess-privaten Teils des virtuellen Adressraum liegen). Wenn der Prozess-spezifische VMM vom Prozess (oder auch von innerhalb des Kernels z.B. bei einem ThreadCreate()) aufgefordert wird neuen virtuellen Speicher innerhalb des Prozesses bereit zu stellen dann sucht dieser in den zugehörigen Verwaltungsstrukturen (die ja im Kernel-Teil des virtuellen Adressraum liegen und somit aus jedem beliebigen Kontext heraus nutzbar sind) ein freies Plätzchen und modifiziert dazu diese Prozess-spezifischen Verwaltungsstrukturen (wozu er den Kernel-VMM benutzt wenn z.B. neue Nodes für den Baum benötigt werden), anschließend hold er neue Pages direkt beim PMM und trägt für diese ein passendes Mapping (die virtuelle Adresse hat der Prozess-spezifische VMM ja selber bestimmt und die physische Adresse kommt vom PMM) in das PD des betreffenden Prozesses ein (die virtuelle Adresse innerhalb des Kernel-Teils an der das PD des Ziel-Prozesses ansprechbar ist steht ja im Prozess-Descriptor, somit ist auch jedes PD aus jedem beliebigen Kontext heraus ansprechbar). Damit das sauber funktioniert muss eben für jeden Prozess ein (möglichst zusammenhängender) Teil im virtuellen Adressraum des Kernels reserviert werden (physischer Speicher wird nur in dem Umfang benötigt wie das PD eben braucht), wenn der Teil des virtuellen Adressraum für den Prozess genau 3GB beträgt dann werden pro PD 3MB+4kB benötigt, das klingt zwar erst mal viel aber wer hat schon mehr als 50 parallele Prozesse am laufen (wenn man eh kein fork() hat). Irgendwelche physischen Speicherbereiche benötigt man dazu nicht im Kernel (erst recht nicht 1:1), auch werden bei einem Micro-Kernel keine HW-Geräte-Speicher im Kernel benötigt, die müssen in den Prozess-Teil des virtuellen Speichers von den Treiber-Prozessen gemappt werden. Bei einem PC der 2GB physischen Speicher hat kann das dann mit nur einem GB Kernel-Adressraum bald eng werden aber da dürfte sich dann der Umstieg auf 64Bit lohnen und wenn Du eh nur 2GB pro Prozess gewähren möchtest hast Du ja genug Reserve im virtuellen Teil für den Kernel.

Der Kernel-VMM funktioniert wieder so ähnlich wie die Heap-Verwaltung im User-Space (ist ja auch der Kernel-Heap) und managed seine eigenen Verwaltungsstrukturen selber. Der Kernel-VMM ist für den Kernel-Teil des virtuellen Adressraum zuständig und weiß auch immer welche Teile da noch frei sind und welche bereits vergeben wurden.


Grüße
Erik (der wirklich hofft das er sich jetzt verständlich ausdrücken konnte)
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 24. November 2011, 16:18
Also erstmal, ab User-VMM sagen wir einfach mal, das ist kein Problem.

Meine Aufteilung ist 3/1, sprich 3GB für den Prozess und 1GB für den Kernel. Das alle PDs immer in den Kernel gemappt sind, will ich einfach nicht, finde ich unschön und unnötig.

Zitat von: erik
Das malloc()/free() kann ja auch nicht für jede Page den Kernel fragen ob es die benutzen kann oder nicht.
Da muss ich dir wiedersprechen, genau das muss es machen. Nicht malloc() bestimmt was es nutzen darf, sondern es fragt beim Kernel nach neuem Speicher. Sonst ist sowas wie ASLR gar nicht möglich. Denn woher soll malloc() wisse wie der Adressraum aussieht?
Dann kommt noch hinzu, das der Kernel den Stack für UserThreads alloziert, wie soll das gehen, wenn der Kernel nicht weiß was malloc() alles für sich beansprucht?
Selbst unter Linux wird doch sbrk() aufgerufen wenn neuer Speicher benltigt wird, das ist doch nix anderes als das Fragen welchen Speicher man nutzen darf!?

Der Kernel-VMM kann also auch nicht so funktionieren wie das User malloc(). Es ist ja schließlich auch ohne weiteres möglich ein User malloc() im Kernel zu nutzen, genau aus dem Grund, weil malloc() halt eine Funktion aufruft um sich neuen Speicher zu holen und dann kommt noch hinzu, dass malloc() für alle Größen "zuständig" ist. Damit meine ich das man malloc() nicht dafür nutzt (nutzen kann) einfach mal ein paar Pages zu allozieren, weil halt gewisse Informationen mit gespeichert werden, sprich wenn du von malloc() 4096 bytes allozierst, dann verbaucht malloc() mind. 4100bytes (4byte um die Größe des Blocks zu wissen).

Ein VMM hingegen gibt grundsätzlich nur vielfaches der Pagegröße raus und das muss auch so sein, z.B. für Shared-Memory oder halt um Pages zu mappen.

Deswegen kommst du auch nicht mit ein oder zwei statischen Pointer weg. Es gibt einen Weg, wie man sich eine "zusätzliche" Datenstruktur sparen kann und das ist indem man jedes Mal das PD (und alle PageTables) auf freie Einträge untersucht und guckt ob man einen Bereich findet der groß genug ist. Dass das aber nicht wirklich das wahre ist, sollte klar sein.

Also muss man irgendwie darüber Buch führen welche Bereiche noch frei sind. Um einfach mal den worst-case zu nehmen, eine Page benutzt, eine Page frei ... und das für den "ganzen" (weil ja in die letzten 4MB das PD gemappt ist) KernelSpace. Wo und wie willst du dir merken welche Pages frei sind und welche nicht? Immerhin sind das 130560 Bereiche und den Speicher wollte ich eigentlich nicht statisch vorreservieren. Dann kommt noch hinzu das man natürlich die Bereiche noch sortiert haben will, um schnell einen Bereich nach der Größe oder der Startadresse zu finden.

Um es ganz einfach zu machen, du sagst ja auch, dass der User-VMM seine Datenstruktur im KernelSpace speichert und dafür den Kernel-VMM nutzt. Nun unterscheide ich aber nicht wirklich zw. Kernel- und User-VMM (wieso auch?). Beide verwalten einfach einen Adressraum einer gewissen Größe und mit einer gewissen Startadresse. Problem beim Kernel-VMM ist halt nur, dass es darunter keinen VMM gibt der genutzt werden kann (Kreisabhängigkeit).

Ich hatte, wie gesagt, am Anfang mal nen VMM der einfach geguckt hat, ich brauche jetzt z.B. ne neue Node und es sind beim SlabAllocator keine mehr vorrätig, also packe ich einfach mal nen neuen ObjectCache in den SlabAllocator für die Nodes. Das ist ersten ein riesiger Hack und zweitens gab das bei mir doch einige Probleme bei vielen CPUs und halt das typische Multithreading Problem, mal funktions mal nicht.

Also habe ich das jetzt alles schön voneinander getrennt und habe für den Kernel-VMM nen "einfachen" Allocator geschrieben, der statisch nen kleinen Bereich (der groß genug ist, um auch den worst-case im Kernel bewältigen zu können) verwaltet.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 24. November 2011, 19:21
Hallo,


Ganz ehrlich FlashBurn, manchmal habe ich so den subjektiven Eindruck das Du mich gar nicht verstehen willst. Ich hatte doch eindeutig geschrieben das die User-Space-Heap-Verwaltung sich bei der Initialisierung den ersten Bereich virtuellen Adressraumes für den Heap beim Kernel holt. Weitere Bereiche (falls mit mehreren unabhängigen Bereichen gearbeitet wird) kommen natürlich auch vom Kernel. Außer einer wirklich kleinen Hand voll Pointer und Größenangaben benötigt die Heap-Verwaltung nichts statisches, es geht darum das die Heap-Verwaltung einen Einstieg in die Verwaltungsstrukturen hat (z.B. einen Pointer auf das Root-Element eines Baums). Ob dieser erste Bereich durch sbrk() ermittelt wird oder als neuer unabhängiger Bereich im virtuellen Adressraum des Prozess alloziert wird (z.B. mit mmap()) spielt für das Prinzip keine Rolle (ist nur ein Implementierungsdetail).


Zitat von: erik
Das malloc()/free() kann ja auch nicht für jede Page den Kernel fragen ob es die benutzen kann oder nicht.
Da muss ich dir wiedersprechen, genau das muss es machen. Nicht malloc() bestimmt was es nutzen darf, sondern es fragt beim Kernel nach neuem Speicher.
Aber nicht bei jedem Aufruf von malloc() sondern immer nur dann wenn der Platz im Heap nicht mehr reicht, dann wird auch gleich eine größere Menge an Speicher (und auch immer in ganzen Pages) beim Kernel beantragt damit dieser teure Vorgang möglichst selten ist. Dieser neue Bereich wird dann als leerer Bereich in die Verwaltungsstrukturen mit eingetragen. Falls mit sbrk() einfach nur der eine Bereich vergrößert wird dann muss das natürlich auch in den Verwaltungsstrukturen passend vermerkt werden.

Das alles gilt auch für die Heap-Verwaltung im Kernel, nur das diese sich beim PMM um neue Pages bemüht. Der Speicher der vom Kernel-Heap kommt wird auch nicht in den User-Mode weitergereicht (geht ja auch nicht weil er im Kernel-Teil des virtuellen Adressraums liegt) und hat auch (üblicherweise) kein Page-Alignment, der Kernel-Heap dient dazu um z.B. die Baum-Elemente (für beide VMMs) oder die Prozess-Descriptoren unterzubringen (also alles Dinge die der Kernel nur intern benötigt).


Das alle PDs immer in den Kernel gemappt sind, will ich einfach nicht, finde ich unschön und unnötig.
Dann hast Du aber ein grundsätzliches Problem beim Allozieren von Speicher für andere Prozesse als den aktuellen, ist natürlich Deine freie Designentscheidung, aber das macht sich bei der Idee mit den PopUp-Threads eher ungünstig (auch wenn es kein absolutes Ausschlusskriterium ist).


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 24. November 2011, 19:44
Zitat von: erik
Ganz ehrlich FlashBurn, manchmal habe ich so den subjektiven Eindruck das Du mich gar nicht verstehen willst.
Sorry, wenn das so rüber kommt. Aber ich hatte deine Erklärung für malloc() halt so verstanden das malloc() den gesamten virtuellen Adressraum selbst verwaltet.

Zitat von: erik
Das alles gilt auch für die Heap-Verwaltung im Kernel, nur das diese sich beim PMM um neue Pages bemüht. Der Speicher der vom Kernel-Heap kommt wird auch nicht in den User-Mode weitergereicht (geht ja auch nicht weil er im Kernel-Teil des virtuellen Adressraums liegt) und hat auch (üblicherweise) kein Page-Alignment, der Kernel-Heap dient dazu um z.B. die Baum-Elemente (für beide VMMs) oder die Prozess-Descriptoren unterzubringen (also alles Dinge die der Kernel nur intern benötigt).
Hmm, das klingt so ähnlich wie ich es vorher hatte und damit hatte ich nur Probleme und empfinde es mehr als Hack als elegant.

Nur um nochmal sicher zu gehen das wir die selbe Sprache sprechen ;) Der VMM verwaltet einfach nen Bereich, der aus einer Startadresse und einer Größe besteht und dabei geht es immer um vielfaches der Pagegröße. Er hat erstmal nix mit dem PMM zu tun.
Man macht beim VMM eine Anfrage nach einem Bereich (in meinem Fall z.B. Vmm::allocZoneKernel(numPages)). Diese Funktion geht durch den Baum und sucht einen Bereich der groß genug ist (best-fit) und wenn er ne neue Node oder nen neuen Bereich erstellen will ruft er einen Allocator auf, um Speicher für die Objekte zu bekommen.

Wie würdest du das lösen? Du redest ja immer davon das der VMM den Speicher seiner Objekte selbst verwaltet. Also würde der VMM wieder durch den Baum gehen um sich eine virtuelle Page zu holen und dorthin Speicher zu mappen, damit er den dann für das Objekt nutzen kann. Diese Page beinhaltet ja mehrere Objekte und auch das musst du ja irgendwie managen. Sprich du hättest dort einen Allocator im Allocator. Finde ich zu ungeschickt und deswegen habe ich da nen "einfachen" Allocator für geschrieben (ist ne Art SlabAllocator nur einfacher).

Mir geht es wirklich nur darum die virtuellen Adressen zu managen, da soll noch gar kein Heap dran hängen, sondern du sollst den VMM nur nach virtuellen freien Adressen fragen, nicht mehr und nicht weniger. Man könnte jetzt wirklich sagen, ich kenne die max. Speichergröße des worst-case, reserviere dafür statisch einen Speicherbereich im KernelSpace und lasse auf diesem Speicherbereich nen ganz normales malloc() arbeiten (ist ja ungefähr das was ich mache).

Mich hätte halt interessiert wie andere das Problem lösen.

Es kann natürlich sein, dass ich immernoch nicht erfasst habe was du meinst. Das einzige was mir noch einfällt ist, dass du sagst, dass ich meinem Kernel malloc() zur Initialisierung ja einfach einen großen Bereich übergeben könnte (was er dann erstmal mit seinen statischen 2 Pointer managen könnte) und dann läuft das schon und malloc() mappt sich den Speicher selbst rein.

So einfach geht das leider auch nicht. Problem an der Stelle ist einfach, das ich die Möglichkeit brauche einfach nur virtuelle Adresse zu bekommen, damit ich da ganz bestimmt Pages hinmappen kann (ohne den PMM danach zu fragen) und da kann ich dann wieder kein malloc() verwenden.

Zumal ich so den Vorteil habe, dass alles schön voneinander getrennt ist und einfach ausgetauscht werden kann.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 24. November 2011, 21:28
Hallo,


Sorry, wenn das so rüber kommt.
Mach Dir nichts draus, jeder hat so seine ganz speziellen Eigenheiten mit denen er mache andere manchmal glatt in den Wahnsinn treiben könnte, das muss die Welt auch mal aushalten. Deine spezielle Eigenheit ist es gerne mal den Wald vor lauter Bäumen zu übersehen. ;)

Nur um nochmal sicher zu gehen das wir die selbe Sprache sprechen ;) Der VMM verwaltet einfach nen Bereich, der aus einer Startadresse und einer Größe besteht und dabei geht es immer um vielfaches der Pagegröße. Er hat erstmal nix mit dem PMM zu tun.
Da möchte ich noch mal explizit auf meinen Beitrag von gestern Abend um 20:09 verweisen. Dort hatte ich doch 4 Ebenen beschrieben und zwei davon mit VMM benahmst (was sicher nicht besonders geschickt ist aber was besseres fällt mir nicht so wirklich ein außer für den Kernel-VMM eben Kernel-Heap). Der VMM der für jeden Prozess den individuellen Teil des virtuellen Adressraums verwaltet (Manager 2 in meiner Auflistung von gestern Abend) benutzt dazu Deine zwei Bäume um eben die freien und belegten Abschnitte im virtuellen Prozess-Adressraum zu verwalten. Diese zwei Bäume gibt es für jeden Prozess individuell so das dieser Prozess-spezifische VMM immer wissen muss für welchen Prozess er gerade arbeitet (außer Du speicherst diese beiden Bäume immer in einem Prozess-privaten Bereich des virtuellen Adressraums, dann ergibt es sich automagisch für welchen Prozess dieser VMM arbeitet anhand des gerade aktiven PD's aber genau das macht Dir ja Probleme weil Du dann öfters das PD wechseln musst).

Man macht beim VMM eine Anfrage nach einem Bereich (in meinem Fall z.B. Vmm::allocZoneKernel(numPages)). Diese Funktion geht durch den Baum und sucht einen Bereich der groß genug ist (best-fit) und wenn er ne neue Node oder nen neuen Bereich erstellen will ruft er einen Allocator auf, um Speicher für die Objekte zu bekommen.
Ja, da ist die Aufgabe des Prozess-spezifischen VMMs. Den Speicher für die Baum-Elemente holt er sich aber vom Kernel-Heap (was Du hier als Allocator bezeichnet hast) und managed die nicht selber (im Gegensatz zum Heap im User-Mode oder auch im Kernel). Wenn der Prozess-spezifische VMM dann in den virtuellen Adressraum für den Prozess echte Pages legen muss holt er diese direkt beim PMM (Manager 4 in meiner Auflistung von gestern Abend) und wenn bestimmte Pages rein sollen dann kommen die eben wo anders her.

Du redest ja immer davon das der VMM den Speicher seiner Objekte selbst verwaltet. Also würde der VMM wieder durch den Baum gehen um sich eine virtuelle Page zu holen und dorthin Speicher zu mappen, damit er den dann für das Objekt nutzen kann.
Das ist nicht die Funktionsweise die ich für den VMM vorsehen würde sondern so arbeitet die Heap-Verwaltung (im User-Space und im Kernel-Space, Manager 1 und 3 in meiner Auflistung von gestern Abend 20:09).

Diese Page beinhaltet ja mehrere Objekte und auch das musst du ja irgendwie managen. Sprich du hättest dort einen Allocator im Allocator.
Jain, und wir reden hier jetzt über den Kernel-Heap (Manager 3 in meiner Auflistung von gestern Abend). Ja, jede Page die zu einem SLAB-Block wird enthält natürlich mehrere der Elemente die der Heap nach draußen (an den restlichen Kernel) gibt (also der Rückgabewert von kmalloc()). Der Kernel-Heap hat also zwei Gründe warum er den PMM nach echten Pages fragen muss: einmal weil er ein paar Pages benötigt um einen neuen SLAB-Block für eine der Objekt-Größen zu bauen (weil für diese Objekt-Größe keine SLABs mehr frei sind) und zum anderen für den Speicher den kmalloc() liefern soll (falls in den Bereichen die bereits zum Kernel-Heap gehören nichts passendes mehr frei ist). Wenn der Kernel-Heap als reiner SLAB-Allocator implementiert ist (was sich bei einem Micro-Kernel ja gerade anbieten würde da dort nur eine sehr überschaubare Menge an unterschiedlichen Objekt-Größen benötigt wird) dann fällt natürlich der zweite Grund weg. Zur Verwaltung der SLAB-Blöcke selber benötigt der Kernel-Heap für jede Objekt-Größe einen statischen Pointer als Einspungspunkt in die verkettete Liste aus SLAB-Blöcken (im Header eines jeden SLAB-Block ist immer mindestens ein Pointer auf den nächsten SLAB-Block drin, besser zwei damit es eine doppelt verkettete Liste wird die sich dann leichter sortieren lässt). Falls dieser Kernel-Heap-SLAB-Allocator noch CPU-lokale Magazine unterstützt benötigt man natürlich noch für jede CPU mal jede Objekt-Größe einen statischen Pointer (hier würde sich ein Array of Structs anbieten, da die Anzahl der CPUs ja nicht schon zur Compile-Zeit bekannt ist) um eben für jede Objekt-Größe auf jeder CPU einen Magazin-Mechanismus verwalten zu können.

Mich hätte halt interessiert wie andere das Problem lösen.
Also dafür bin ich der falsche Ansprechpartner, bei mir werden die meisten Dinge zwar sehr ähnlich werden aber einige Details werden wegen meinen Segmenten auch ganz anders ausfallen.

Problem an der Stelle ist einfach, das ich die Möglichkeit brauche einfach nur virtuelle Adresse zu bekommen, damit ich da ganz bestimmt Pages hinmappen kann
Das trifft auf den Prozess-spezifischen VMM (Manager 2 in meiner Auflistung von gestern Abend) selbstverständlich zu aber nicht auf den Kernel-Heap (Manager 3 in meiner Auflistung von gestern Abend) da es Dir innerhalb des Kernels für all Deine Verwaltungsstrukturen (egal ob Bäume oder Prozess/Thread-Descriptoren oder sonstwas) egal sein kann in was für Pages die liegen. Was der Kernel-Heap liefert hat auch keinen Bezug zur Page-Größe und kein besonderes Alignment (egal ob der Kernel-Heap als reiner SLAB-Allocator oder als generische Variante oder als Kombination aus beidem realisiert ist).

Zumal ich so den Vorteil habe, dass alles schön voneinander getrennt ist und einfach ausgetauscht werden kann.
Das bleibt ja auch bei meinem Vorschlag erhalten (nur mit dem Unterschied das meine 4 Ebenen jeweils etwas weniger komplex sind ;)).


Grüße
Erik


PS.: FlashBurn, Bitte verliere den Wald nicht aus den Augen, ließ lieber mehrmals. Ich weiß das ich kein toller Erklärer bin, auch weil ich oft versuche möglichst viele Details mit rein zu bringen (um eben ein möglichst vollständiges Bild zu liefern) und andere so sicher Probleme haben dem Wesentlichen zu folgen.
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 24. November 2011, 21:48
Zitat von: erik
Ja, da ist die Aufgabe des Prozess-spezifischen VMMs. Den Speicher für die Baum-Elemente holt er sich aber vom Kernel-Heap (was Du hier als Allocator bezeichnet hast) und managed die nicht selber (im Gegensatz zum Heap im User-Mode oder auch im Kernel). Wenn der Prozess-spezifische VMM dann in den virtuellen Adressraum für den Prozess echte Pages legen muss holt er diese direkt beim PMM (Manager 4 in meiner Auflistung von gestern Abend) und wenn bestimmte Pages rein sollen dann kommen die eben wo anders her.
So, ich unterscheide aber nicht zw. Kernel- und User-VMM. Ist eigentlich genau das gleiche (theoretisch könnte ich den Code sogar fürs ID-Management einsetzen), hat nur nen unterschiedlichen Startwert und ne unterschiedliche Größe.

Zitat von: erik
Jain, und wir reden hier jetzt über den Kernel-Heap (Manager 3 in meiner Auflistung von gestern Abend). Ja, jede Page die zu einem SLAB-Block wird enthält natürlich mehrere der Elemente die der Heap nach draußen (an den restlichen Kernel) gibt (also der Rückgabewert von kmalloc()). Der Kernel-Heap hat also zwei Gründe warum er den PMM nach echten Pages fragen muss: einmal weil er ein paar Pages benötigt um einen neuen SLAB-Block für eine der Objekt-Größen zu bauen (weil für diese Objekt-Größe keine SLABs mehr frei sind) und zum anderen für den Speicher den kmalloc() liefern soll (falls in den Bereichen die bereits zum Kernel-Heap gehören nichts passendes mehr frei ist).
Auch wenn das Wort Heap gerne dafür verwendet wird, mag ich es nicht. Denn die meisten assozieren damit einfach einen bereich im virtuellen Adressraum der dem Stack entgegenwächst und das trifft für meinen VMM einfach nicht zu.

Zitat von: erik
Das trifft auf den Prozess-spezifischen VMM (Manager 2 in meiner Auflistung von gestern Abend) selbstverständlich zu aber nicht auf den Kernel-Heap (Manager 3 in meiner Auflistung von gestern Abend) da es Dir innerhalb des Kernels für all Deine Verwaltungsstrukturen (egal ob Bäume oder Prozess/Thread-Descriptoren oder sonstwas) egal sein kann in was für Pages die liegen.
Das trifft bei mir auf den Kernel- und User-VMM zu. Ich brauche das, da ich auch Pages mappen möchte und die müssen wirklich an der Pagegröße alignt sein. Frag mich nicht warum, aber ich trenne das gerne so gut es geht (und ich weiß dass das eigentlich gar kein OO Konzept ist, durfte ich mir schon oft von meinem Prof anhören) und deswegen habe ich einmal den VMM und einmal den SlabAllocator.

Zitat von: erik
Das bleibt ja auch bei meinem Vorschlag erhalten (nur mit dem Unterschied das meine 4 Ebenen jeweils etwas weniger komplex sind ;)).
Eben nicht, bei deinem Vorschlag (wenn ich ihn denn richtig verstanden habe) hätte der SlabAllocator auch noch die Funktion des VMMs und ich könnte keine Bereiche mehr allozieren (wo ich dann irgendwelche Pages reinmappen kann).

Ich kann dir als Bsp. die IO-Permission-Bitmap nennen, die IO-APICs, Stacks und es gibt bestimmt noch ein paar Sachen, die mir jetzt nicht einfallen. Wo ich einen VMM im Kernel brauche der mir virtuelle Bereiche ohne physischen Speicher liefert.

Und was ich als sehr großen Vorteil erachte, ich kann alle Ebenen ganz leicht austauschen ohne an einer anderen etwas ändern zu müssen. Bei deiner Variante wäre es ja nicht so einfach mal den "Kernel-Heap" auszutauschen. Ich kann theoretisch einfach nen allgemeinen malloc() nehmen und muss nur den Code zum alllozieren und freigeben für Speicher anpassen (was genau 2 Funktionsaufrufe sind).
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 26. November 2011, 19:06
Hallo,


Ich brauche das, da ich auch Pages mappen möchte und die müssen wirklich an der Pagegröße alignt sein.
Hm, stimmt, hatte ich vergessen. Also der Kernel-Heap muss nicht nur in der Lage sein Objekte zu liefern sondern auch ganze virtuelle Pages (ohne gleich zwangsläufig physischen Speicher dahinter zu legen, sondern nur optional). Diese Fähigkeit muss er doch eigentlich sowieso haben da er ja auch ganze Pages benutzen muss um daraus SLAB-Blöcke zu bauen (und was anderes als ganze Pages können auch nicht mit Hilfe des PMM mit echtem physischen Speicher hinterlegt werden). Dann musst Du diese interne Fähigkeit des Kernel-Heap als zusätzliches Interface verfügbar machen. Der Kernel-Heap muss doch eh intern einen Baum pflegen um den virtuellen Kernel-Speicher zu managen (so wie der Prozess-VMM den virtuellen Speicher der Prozesse managed, nur mit dem Unterschied das der Prozess-VMM für seine Baum-Objekte einfach den Kernel-Heap benutzt und der Kernel-Heap dafür sich selbst benutzen muss).

Ich sehe da noch immer kein schwerwiegendes Problem.

Ist eigentlich genau das gleiche (theoretisch könnte ich den Code sogar fürs ID-Management einsetzen), hat nur nen unterschiedlichen Startwert und ne unterschiedliche Größe.
So wie ich das sehe können auch in meiner Idee sich Prozess-VMM und Kernel-Heap eine erhebliche Menge Code teilen (das mit dem Baum zur Verwaltung des jeweiligen virtuellen Adressraums ist ja eigentlich das Gleiche), nur die jeweiligen Pointer auf die Baum-Wurzel sind verschieden.

Und was ich als sehr großen Vorteil erachte, ich kann alle Ebenen ganz leicht austauschen ohne an einer anderen etwas ändern zu müssen. Bei deiner Variante wäre es ja nicht so einfach mal den "Kernel-Heap" auszutauschen.
Warum soll das bei meinem Vorschlag nicht gehen? Solange man jeder Ebene ein sauberes Interface verpasst und die anderen Ebenen dieses Interface korrekt benutzen kann man auch jede Ebene individuell beliebig austauschen.

So, ich unterscheide aber nicht zw. Kernel- und User-VMM.
Dann eben nicht, sorry, aber das ist Deine Designentscheidung. Ich versuche Dir nur einen Weg zu zeigen von dem ich glaube (nicht wissen) das er Deine Probleme löst. Ideologische Scheuklappen sind da nicht immer angebracht.

Auch wenn das Wort Heap gerne dafür verwendet wird, mag ich es nicht.
Namen sind nicht so arg wichtig, klar sollte man immer etwas darauf achten was andere jeweils damit assoziieren aber auch der Heap im User-Mode wächst schon sehr lange nicht mehr einfach nur dem Stack entgegen (schon allein deswegen weil heutige Prozesse überwiegend mehrere Stacks für mehrere Threads haben). Ich persönlich empfinde den Begriff Heap für den Kernel-VMM eigentlich als ganz angemessen, es ist ja im Endeffekt ein Heap.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 26. November 2011, 19:29
Zitat von: erik
Also der Kernel-Heap muss nicht nur in der Lage sein Objekte zu liefern sondern auch ganze virtuelle Pages (ohne gleich zwangsläufig physischen Speicher dahinter zu legen, sondern nur optional). Diese Fähigkeit muss er doch eigentlich sowieso haben da er ja auch ganze Pages benutzen muss um daraus SLAB-Blöcke zu bauen (und was anderes als ganze Pages können auch nicht mit Hilfe des PMM mit echtem physischen Speicher hinterlegt werden). Dann musst Du diese interne Fähigkeit des Kernel-Heap als zusätzliches Interface verfügbar machen. Der Kernel-Heap muss doch eh intern einen Baum pflegen um den virtuellen Kernel-Speicher zu managen (so wie der Prozess-VMM den virtuellen Speicher der Prozesse managed, nur mit dem Unterschied das der Prozess-VMM für seine Baum-Objekte einfach den Kernel-Heap benutzt und der Kernel-Heap dafür sich selbst benutzen muss).
Und das empfindest du nicht als Hack? Weil ich ja immer den jeweiligen Allocator um eine Funktionalität erweitern muss, die er normalerweise nicht erfüllen muss.

Also für mich hat der SlabAllocator nix mit der Verwaltung virtueller Adressen zu tun, das ist gar nicht seine Aufgabe. Anders gefragt, wieso findest du eine Ebene mehr beim User ok und beim Kernel nicht? Mit der Ebene mehr meine ich das was ich unter einem VMM verstehe, sprich das Verwalten virtueller Adressen/Pages.

Zitat von: erik
Warum soll das bei meinem Vorschlag nicht gehen? Solange man jeder Ebene ein sauberes Interface verpasst und die anderen Ebenen dieses Interface korrekt benutzen kann man auch jede Ebene individuell beliebig austauschen.
Wenn ich die Verwaltung für die virtuellen Adressen ändern möchte, müsste ich bei deiner Idee am SlabAllocator rumspielen bzw. wenn ich den SlabAllocator gegen was anderes austauschen möchte, muss ich auch den neuen Allocator dahingehend anpassen, dass er diese Verwaltung mit beinhaltet. Das ist für mich halt weder sauber getrennt noch einfacher.

Du baust zw. beiden eine zu große Abhängigkeit voneinander auf. Um nochmal mein Bsp zu bringen. Bei deiner Variante ist es nicht einfach möglich den Allocator auszutauschen, bei meiner schon.

Ich bin, was deine Idee betrifft, auch leider schon negativ vorbelastet. Ich hatte, wie gesagt, vorher den SlabAllocator für die Objekte des VMMs mit genutzt und das gab nur Probleme und war ein einziger Hack. Alleine schon deswegen, weil ich von außerhalb des SlabAllocators Pages für bestimmte Objekte "injezieren" musste.

Im Endeffekt geht es ja darum, dass ich um Speicher in einem anderen Prozess zu allozieren, dass PD wechseln muss. Davon ausgehend dass das eigentlich nur der Fall ist wenn ich sowieso an einen Thread in dem anderen Prozess abgebe (mir fällt gerade kein wirklicher Fall ein, wo das nicht so ist, es gibt ihn aber bestimmt), dürfte das doch nicht so das Problem sein oder?

Ich weiß ich reite immer gerne auf dem worst-case rum, aber der kommt manchmal schneller als man denkt. Mir gefällt an der Variante das die User-VMMs alle den SlabAllocator nutzen nicht, dass im worst-case eine riesige Speicherverschwendung auftritt. Mir ist auch klar dass das gleiche Problem auch bei meiner Variante (jeder User-VMM nutzt praktisch seinen eigenen SlabAllocator) auftritt, aber halt in wesentlich kleiner Ausführung. Dem könnte man entgegnen dass bei deiner Variante der verschwendete Speicher wieder von anderen User-VMMs genutzt werden kann und bei meiner nicht.

Auf der anderen Seite, ich kann es zu gegebener Zeit auch einfach mal Testen, dazu muss ich genau einen Konstrukturaufruf ändern (2 Werte) und es wird der allgemeine SlabAllocator dafür genutzt.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 26. November 2011, 21:12
Hallo,


Und das empfindest du nicht als Hack?
Eigentlich nicht, nö.
Das Problem ist das der Slab-Allocator ganze Pages braucht (z.B. von einem VMM) aber zur Verwaltung dieser Pages (im virtuellen Adressraum) benötigt man wieder passende Verwaltungsstrukturen (z.B. einen Baum) und dafür bietet sich wieder der Slab-Allocator an (ist ja auch seine Spezialität). Daraus ergibt sich dann ganz schnell eine eklige Kreisabhängigkeit die auch wieder blöde Probleme erzeugen kann, aus diesem Grund betrachte ich es nicht als Hack das beides zu einem Stück zusammen zu fassen.
In meinem OS möchte ich aber genau diese beiden Dinge voneinander trennen und muss dafür mit der Kreisabhängigkeit klar kommen (ich denke das wird mir auch gelingen), Svenska würde gerade das einen ekligen Hack nennen.
Aus meiner Sicht ist beides Okay, man muss es nur ordentlich umsetzen. Einen einfachen Königsweg der dieses Problem komplett vermeidet (und auch keine sonstigen Nachteile bringt) gibt es wohl nicht, ich kenne zumindest keinen.

Das ist für mich halt weder sauber getrennt noch einfacher.
Wenn Du das trennen möchtest dann nur zu aber dann musst Du auch mit der Kreisabhängigkeit klar kommen, oder wo her soll sich der Kernel-VMM (unter dem Kernel-Heap-Slab-Allocator) seine Verwaltungsstrukturen holen?

Im Endeffekt geht es ja darum, dass ich um Speicher in einem anderen Prozess zu allozieren, dass PD wechseln muss. Davon ausgehend dass das eigentlich nur der Fall ist wenn ich sowieso an einen Thread in dem anderen Prozess abgebe (mir fällt gerade kein wirklicher Fall ein, wo das nicht so ist, es gibt ihn aber bestimmt), dürfte das doch nicht so das Problem sein oder?
So aus dem leeren Bauch heraus kann ich auch nicht abschätzen wie viele Situationen es gibt das man aus dem Kontext des einen Prozess am Speichermanagement eines anderen Prozesses drehen muss aber ich könnte mir vorstellen das da vielleicht Dinge wie Memory-Sharing oder gar Memory-Mapped-Files (wo das VFS im Adressraum anderer Prozesse rumhantieren muss, das geht mit meinen Segmenten auf jeden Fall einfacher zu lösen) gewisse Anforderungen stellen. Ich schätze daher das es für die Zukunft nicht schadet wenn sowas gut funktioniert.

Ich weiß ich reite immer gerne auf dem worst-case rum
Kein Problem, an den muss gedacht werden. Ich denke unsere zwei Varianten unterschieden sich vom Speicherverbrauch nicht viel (und von der Performance sicher auch nicht), es wird nur in verschiedenen Abschnitten des virtuellen Adressraum gebucht. Klar könnte das in einem Kernel mit nur einem einzigen GB an virtuellem Adressraum eher knapp werden als wenn das alles Prozess-lokal läuft aber ich denke so kritisch ist das nicht und wenn doch ist es vielleicht ein guter Grund auf 64Bit umzusteigen. ;)


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 26. November 2011, 21:32
Zitat von: erik
Wenn Du das trennen möchtest dann nur zu aber dann musst Du auch mit der Kreisabhängigkeit klar kommen, oder wo her soll sich der Kernel-VMM (unter dem Kernel-Heap-Slab-Allocator) seine Verwaltungsstrukturen holen?
Naja, es klingt wahrscheinlich wieder blöd weil es von mir kommt, aber dazu habe ich noch nen Allocator geschrieben ;) Der ist aber einfacher und vorallem statisch. Ich lege zur Compilezeit nen Bereich fest und den verwaltet er und dazu braucht er keinerlei dynamischen Speicher. Der zusätzliche Verbauch liegt bei 8-16byte pro benötigter Page.

Zitat von: erik
Ich denke unsere zwei Varianten unterschieden sich vom Speicherverbrauch nicht viel (und von der Performance sicher auch nicht), es wird nur in verschiedenen Abschnitten des virtuellen Adressraum gebucht.
Sie skalieren nur anders. Meine Variante hat als einzigen Engpass den Prozess und deine den allgemeinen Kernel-Allocator.

Was mir gerade noch klar geworden ist, auch bei deiner Variante müsste ich das PD wechseln oder zumindest in Teilen in den Kernel mappen, da ich ja auch Speicher in die PageTables eintragen muss. Von daher finde ich einen extra VMM schon besser und auch das Wechseln des PDs sollte einfacher sein, als Teile zu mappen und sich nur mehr Komplexität einzuhandeln.

Zitat von: erik
Klar könnte das in einem Kernel mit nur einem einzigen GB an virtuellem Adressraum eher knapp werden als wenn das alles Prozess-lokal läuft aber ich denke so kritisch ist das nicht und wenn doch ist es vielleicht ein guter Grund auf 64Bit umzusteigen.
Auf 64bit möchte ich fürs erste verzichten, wenn ich denn irgendwann mal soweit bin, dass ne Konsole läuft und ich ein paar Treiber habe, kann ich mir darüber Gedanken machen. Bis dahin werde ich noch auf viele Probleme stoßen und diese ganzen Erfahrungen helfen dann dabei für ein 64bit OS "bessere" Entscheidungen zu treffen.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 27. November 2011, 11:29
Hallo,


Naja, es klingt wahrscheinlich wieder blöd weil es von mir kommt, aber dazu habe ich noch nen Allocator geschrieben ;) Der ist aber einfacher und vorallem statisch. Ich lege zur Compilezeit nen Bereich fest und den verwaltet er und dazu braucht er keinerlei dynamischen Speicher. Der zusätzliche Verbauch liegt bei 8-16byte pro benötigter Page.
Nunja, also gerade elegant oder effizient klingt das tatsächlich nicht (und das nicht nur weil es von Dir kommt). Wenn Dein Kernel 1 GB, also 262'144 Pages, belegt dann macht das 2 MB bis 4 MB statischen Verbrauch für Deinen Mini-Allocator. Mir persönlich wäre das zu viel. Vor allem ist es IMHO doppelter Unsinn weil Du doch schon einen tollen SLAB-Allocator hast.

Sie skalieren nur anders.
Das ist richtig, aber beim SLAB-Allocator kann man da ja mit dem CPU-lokalen Magazin-Mechanismus entgegen wirken.

Was mir gerade noch klar geworden ist, auch bei deiner Variante müsste ich das PD wechseln oder zumindest in Teilen in den Kernel mappen, da ich ja auch Speicher in die PageTables eintragen muss.
Deswegen hatte ich ja auch eigentlich Vorgeschlagen das alle PDs immer im virtuellen Adressraum des Kernels sichtbar sind, das bringt IMHO maximale Flexibilität und geringste Komplexität.
Wenn ich Dich richtig verstanden habe willst Du doch das oberste GB des virtuellen Adressraums dem Kernel geben, das zweitoberste GB ist dann Prozess-lokal aber trotzdem nur für den Kernel zugänglich und der Prozess bekommt dann die unteren 2 GB. Dann gib doch dem Kernel gleich die ganzen oberen 2 GB und schon ist Dein Problem weitestgehend gelöst. Und wie viel Speicher der Kernel-VMM vom Kernel-Heap zur Verwaltung der 2 GB virtuellen Kernel-Adressraums benötigt hängt dann im wesentlichen davon ab wie gut Du die Fragmentierung in den Griff bekommst und das sollte sich doch innerhalb des Kernel einigermaßen gut lösen lassen (zumindest sollten da keine 2 bis 4 MB drauf gehen).

und diese ganzen Erfahrungen helfen dann dabei für ein 64bit OS "bessere" Entscheidungen zu treffen.
Bei einem 64Bit-OS trifft man ganz andere Entscheidungen. Dort wird man z.B. immer den gesamten physischen Speicher (mitsamt aller HW-Geräte) in den virtuellen Kernel-Adressraum 1:1 einblenden, einfach weil es bequem machbar ist und ne Menge grauer Haare erspart.


Was ich mich noch frage ist warum Du überhaupt so wesentliche Teile Deines Kernels wie die Speicherverwaltung austauschbar haben willst. Die Speicherverwaltung ist IMHO eine der wichtigsten Komponenten in einem OS-Kernel (bei einem Micro-Kernel sicher auch eine der größten, was Code-Umfang usw. angeht), der Kernel wird sich an vielen Stellen auch implizit auf ein bestimmtes Verhalten der Speicherverwaltung verlassen so das ein Austauschen wahrscheinlich trotz klarer API gar nicht so einfach ist wie Du jetzt vielleicht denkst. In meinem Design betrachte ich den Micro-Kernel als relativ monolithische Einheit, klar werden da ein paar Dinge (wie z.B. der Treiber für den IRQ-Controller oder den HW-Timer) auf Quell-Code-Ebene recht modular und austauschbar sein aber die wesentlichen Kernelemente sind aus einem Guss. Eine andere Herangehensweise macht IMHO auch keinen echten Sinn. Soweit wie beim L4, wo man sagt das (fast) jede Architektur-Variante ihren eigenen speziell angepassten Kernel bekommt, muss man ja auch nicht unbedingt gehen aber das Gegenteil davon, was Du wohl momentan versuchst zu erreichen, ist IMHO ebenfalls nicht sehr zielführend.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 27. November 2011, 12:06
Zitat von: erik
Wenn Dein Kernel 1 GB, also 262'144 Pages, belegt dann macht das 2 MB bis 4 MB statischen Verbrauch für Deinen Mini-Allocator. Mir persönlich wäre das zu viel.
Da habe ich dann mal wieder zu wenig Infos preisgegeben. Mit statisch meinte ich eigentlich die größe des Bereichs, es werden auch dort Pages so wie sie gebraucht werden reingemappt, aber ich muss nicht Buch führen wie groß der freie Bereich ist oder ob noch genug frei ist, weil der Bereich der verwaltet wird groß genug für den worst-case ist (plus ein wenig mehr, um ein vernünftiges Alignment zu bekommen).

Dieser Allocator ist ein sehr vereinfachter SlabAllocator, halt nur ohne die große dynamische Verwaltung. Im Endeffekt könnte man sagen, dass ist das was du mir die ganze Zeit vorschlägst nur für nen ganz kleinen statisch festgelegten Bereich.

Zitat von: erik
Wenn ich Dich richtig verstanden habe willst Du doch das oberste GB des virtuellen Adressraums dem Kernel geben, das zweitoberste GB ist dann Prozess-lokal aber trotzdem nur für den Kernel zugänglich und der Prozess bekommt dann die unteren 2 GB.
Jetzt könnte ich auch schreiben, dass du mich einfach nicht verstehen willst :P Ich habe eine 3/1 Aufteilung, also 3GB Prozess und 1GB Kernel. Es gibt allerdings im KernelSpace noch einen kleinen (8MB oder so) Prozess-lokalen Bereich für den User-VMM.

Zitat von: erik
Bei einem 64Bit-OS trifft man ganz andere Entscheidungen. Dort wird man z.B. immer den gesamten physischen Speicher (mitsamt aller HW-Geräte) in den virtuellen Kernel-Adressraum 1:1 einblenden, einfach weil es bequem machbar ist und ne Menge grauer Haare erspart.
Du bist doch immer der, der meint das man auch einen Counter der erst in über 100Jahren überläuft so programmieren sollte, das man mit dem Fall umgehen kann. Aber du willst den physischen Speicher 1:1 mappen?
Was ist wenn in 100Jahren wieder die selbe Situation wie heute (also pyhsischer Speicher > virtueller unter 32bit) eingetreten ist? Mal ganz davon abgesehen, dass dann wahrscheinlich das ganze OS alles andere als noch geeignet sein wird.

Zitat von: erik
Was ich mich noch frage ist warum Du überhaupt so wesentliche Teile Deines Kernels wie die Speicherverwaltung austauschbar haben willst.
Ich bastle gern und will halt mal zusehen, dass ich ein vernünftiges stabiles Interface zustande bekomme. Zumal ich mir halt so die Möglichkeit offen halte, einfach den Allocator austauschen zu können. Es gibt ja immer mal wieder richtig gute neue und dann habe ich nicht viel Aufwand meinen Kernel "anzupassen".

Zitat von: erik
Soweit wie beim L4, wo man sagt das (fast) jede Architektur-Variante ihren eigenen speziell angepassten Kernel bekommt, muss man ja auch nicht unbedingt gehen
Ist es sehr schlecht wenn ich dir jetzt sage, dass das genau meine Meinung bei einem MikroKernel ist ;) Der Kernel ist doch wirklich nicht so groß und da sollte man zusehen, dass man das beste aus der Architektur rausholt. Zumal ich kein Fan von den ganzen Präprozessor if´s, die es insbesondere im Linux-Kernel, aber auch in den meisten libc´s gibt.

Dann lieber komplett neuen angepassten Kernel, aber auch dort kann Code wieder verwendet werden. Allerdings nur wenn es ohne Präprozessor if´s geht.

Ich habe mir inzw. schon einige "wie schreibt man guten Code"-Bücher mal angeguckt und die verfolgen z.B. auch nen ganz anderes Ziel als optimalen binären Code. Der Code soll leicht lesbar sein und die Performance kommt erst irgendwann ganz ganz weit hinten.

Was ich damit sagen will, jeder hat so seine eigenen Ziele und mir gefällt es besser wenn diese Ebenen der Speicherverwaltung durch klar definierte Interfaces getrennt sind. Dass das auch Probleme gibt gehört halt zum Kompromiss dazu.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 06. January 2012, 20:41
Hallo,


da momentan das Aufwärmen alter Threads gerade Mode ist will ich hier noch mal ansetzen. ;)


Da habe ich dann mal wieder zu wenig Infos preisgegeben.
Ja. Du hast z.B. immer noch nicht angegeben wie groß der Bereich, den Dein Mini-Allocator verwaltet, eigentlich ist. Zum anderen halte ich es auch nicht für sinnvoll das statisch festzulegen, dieser Speicher ist dann für andere Zwecke verloren.
Wenn ich Dich richtig verstanden habe willst Du darin die Verwaltungsdaten für den Kernel-Heap unterbringen, richtig?

aber ich muss nicht Buch führen wie groß der freie Bereich ist oder ob noch genug frei ist, weil der Bereich der verwaltet wird groß genug für den worst-case ist (plus ein wenig mehr, um ein vernünftiges Alignment zu bekommen).
Also das erscheint mir etwas zu magisch, zumindest musst Du wissen wo Du neue Pages hinmappen kannst und Du solltest auch noch zumindest einen einfachen Integerwert haben der Dir sagt wie viel noch frei ist.

Dieser Allocator ist ein sehr vereinfachter SlabAllocator, halt nur ohne die große dynamische Verwaltung. Im Endeffekt könnte man sagen, dass ist das was du mir die ganze Zeit vorschlägst nur für nen ganz kleinen statisch festgelegten Bereich.
Nein, was ich verschlage ist den bereits vorhanden SLAB-Allocator für alles zu nutzen und nicht noch einen zusätzlichen (wenn auch primitiven) dazu zubauen.

Zitat von: erik
Wenn ich Dich richtig verstanden habe willst Du doch das oberste GB des virtuellen Adressraums dem Kernel geben, das zweitoberste GB ist dann Prozess-lokal aber trotzdem nur für den Kernel zugänglich und der Prozess bekommt dann die unteren 2 GB.
Jetzt könnte ich auch schreiben, dass du mich einfach nicht verstehen willst :P Ich habe eine 3/1 Aufteilung, also 3GB Prozess und 1GB Kernel.
Du hast bisher gar keine konkreten Informationen über das Layout Deines virtuellen Adressraums gegeben, mit "Wenn ich Dich richtig verstanden habe" hab ich doch klar ausgedrückt das ich nur spekuliere.

Es gibt allerdings im KernelSpace noch einen kleinen (8MB oder so) Prozess-lokalen Bereich für den User-VMM.
Das heist dieser Bereich gehört noch zu dem oberen 1 GB aber es gibt dort für jeden Prozess individuelle PTs (also in jedem Prozess ist dort anderer physischer Speicher eingebunden)?

Du bist doch immer der, der meint das man auch einen Counter der erst in über 100Jahren überläuft so programmieren sollte, das man mit dem Fall umgehen kann. Aber du willst den physischen Speicher 1:1 mappen?
Ja, ich bin der Meinung das man an möglichst alle Eventualitäten denken sollte und genau deswegen würde ich in den Start-Code des Kernels eine Abfrage einbauen die prüft ob der tatsächlich benutzte physische Adressraum klein genug ist um in den virtuellen Adressraum des Kernels komplett und bequem rein zu passen ansonsten gibt es eine Fehlermeldung "To much Memory".

Das :
Zumal ich mir halt so die Möglichkeit offen halte, einfach den Allocator austauschen zu können.
und das :
Ist es sehr schlecht wenn ich dir jetzt sage, dass das genau meine Meinung bei einem MikroKernel ist ;) Der Kernel ist doch wirklich nicht so groß und da sollte man zusehen, dass man das beste aus der Architektur rausholt.
widerspricht sich irgendwie. Auf der einen Seite möchtest Du möglichst viel Flexibilität und auf der anderen willst Du die Meinung vertreten das ein Micro-Kernel ruhig möglichst aus einem Guss sein soll, ich bin verwirrt.

Zumal ich kein Fan von den ganzen Präprozessor if´s, die es insbesondere im Linux-Kernel, aber auch in den meisten libc´s gibt.
Diese Einstellung findet meine uneingeschränkte Zustimmung. ;)

mir gefällt es besser wenn diese Ebenen der Speicherverwaltung durch klar definierte Interfaces getrennt sind.
Dann musst Du aber auch alle indirekten Nebeneffekte mit berücksichtigen in Deiner Interface-Beschreibung (die zu diesem Zweck wirklich schriftlich erfolgen sollte damit Du auch in Jahren möglichst kein Detail aus den Augen verlierst). Ich hab bei mir z.B. mit beschrieben welche Locks frei sein müssen wenn bestimmte Funktionen mit bestimmten Parametern aufgerufen werden.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 06. January 2012, 21:08
Zitat von: erik
Ja. Du hast z.B. immer noch nicht angegeben wie groß der Bereich, den Dein Mini-Allocator verwaltet, eigentlich ist.
Doch, hast du weiter unten sogar gequotet ;) Der ist ca. 8MB oder so groß, kann ich dir genau gar nicht sagen, weil das der Präprozessor (bzw. Templates) ausrechnet. Es wird aber auf 4MB gerundet, zwecks PTs.

Zitat von: erik
Zum anderen halte ich es auch nicht für sinnvoll das statisch festzulegen, dieser Speicher ist dann für andere Zwecke verloren.
Wenn ich Dich richtig verstanden habe willst Du darin die Verwaltungsdaten für den Kernel-Heap unterbringen, richtig?
Jap, der Bereich ist zur Verwaltung des Kernel-Heaps da und er ist statisch zwecks Henne-Ei-Problem bzw. Kreis-Abhängigkeiten!

Zitat von: erik
Also das erscheint mir etwas zu magisch, zumindest musst Du wissen wo Du neue Pages hinmappen kannst und Du solltest auch noch zumindest einen einfachen Integerwert haben der Dir sagt wie viel noch frei ist.
Also ja, ich habe ne Bitmap (für die gemappten Pages) und ne "verkettete Liste" (ist mehr nen Array mit verketteten Indizes). Soweit ich weiß führe ich nicht wirklich Buch wie viel noch frei ist. Ich habe mehr Speicher zur Verfügung als der worst-case ihn benötigt.

Zitat von: erik
Nein, was ich verschlage ist den bereits vorhanden SLAB-Allocator für alles zu nutzen und nicht noch einen zusätzlichen (wenn auch primitiven) dazu zubauen.
Aber ich kann diesen SlabAllocator nicht einfach gegen z.B. dlmalloc austauschen ohne dlmalloc noch modifizieren zu müssen. Bei meiner Variante geht das und das war/ist mein Ziel.

Zitat von: erik
Du hast bisher gar keine konkreten Informationen über das Layout Deines virtuellen Adressraums gegeben
Ich bin mir eigentlich ziemlich sicher das ich das in diesem Thread schonmal gepostet hatte.

Zitat von: erik
Das heist dieser Bereich gehört noch zu dem oberen 1 GB aber es gibt dort für jeden Prozess individuelle PTs (also in jedem Prozess ist dort anderer physischer Speicher eingebunden)?
Jap, ist aber kein Problem da es immer ganze PTs sind.

Zitat von: erik
Ja, ich bin der Meinung das man an möglichst alle Eventualitäten denken sollte und genau deswegen würde ich in den Start-Code des Kernels eine Abfrage einbauen die prüft ob der tatsächlich benutzte physische Adressraum klein genug ist um in den virtuellen Adressraum des Kernels komplett und bequem rein zu passen ansonsten gibt es eine Fehlermeldung "To much Memory".
Sorry, aber das wiederspricht sich mMn ja "alle Eventualitäten denken" und "Fehlermeldung "To much Memory"". Zumal du dann wieder genau das gleiche Problem wie der Linux-Kernel hast (und genau das will ich auch nicht). Du hast 64MB frei, brauchst 128KB, aber der größte zusammenhängende Bereich ist nur 64KB groß!

Zitat von: erik
widerspricht sich irgendwie. Auf der einen Seite möchtest Du möglichst viel Flexibilität und auf der anderen willst Du die Meinung vertreten das ein Micro-Kernel ruhig möglichst aus einem Guss sein soll, ich bin verwirrt.
Aus meiner Sicht wiederspricht sich das nicht. Was ich bei dem MikroKernel für jede Architektur meinte ist doch, dass man alle Features so nutzt wie sie vorhanden sind (Hardware) und nicht andere drüber stülpt (Software) damit es auf allen Architekturen gleich ist.
Ich würde/werde für jede Architektur nen anderen HAL schreiben.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 07. January 2012, 14:48
Hallo,


Doch, hast du weiter unten sogar gequotet ;) Der ist ca. 8MB oder so groß ...
Aha, da hab ich wohl den Zusammenhang aus den Augen verloren, sorry.

und er ist statisch zwecks Henne-Ei-Problem bzw. Kreis-Abhängigkeiten!
Gut, das mit dem statisch kann ich zwar verstehen und nachvollziehen (Henne-Ei-Probleme und Kreis-Abhängigkeiten sind eklig) aber ist meiner persönlichen Meinung nach trotzdem ein wenig Verschwendung. Aber es ist Deine Design-Entscheidung und gut.

Sorry, aber das wiederspricht sich mMn ja "alle Eventualitäten denken" und "Fehlermeldung "To much Memory"".
Wo widerspricht sich das? Ich als Programmierer denke an die Eventualität das auch mal mehr physischer RAM im System sein könnte als mit dem im OS-Kernel implementierten Mechanismus sinnvoll verwaltet werden kann und deswegen fange ich das ab und gebe eine aussagekräftige Fehlermeldung. Ich denke das ist genau das was ich meine wenn ich sage das man als Programmierer auch mit ungewöhnlichen/unerwarteten/unmöglichen Randfällen umgehen sollte. Die maximale Menge an physischen Adressraum ist ja nichts was sich dynamisch zur Laufzeit ändert (deswegen muss man das auch nicht wie einen theoretisch überlaufenden Counter zur Laufzeit handhaben) sondern steht zur Boot-Zeit fest und das OS kann mit einer einzelnen Abfrage hier auf Nummer sicher gehen. An der selben Stelle im Boot-Code sollte auch noch eine Abfrage sein ob mindestens X MBytes an physischen RAM vorhanden sind damit das OS nicht schon beim Booten abstürzt.

Zumal du dann wieder genau das gleiche Problem wie der Linux-Kernel hast (und genau das will ich auch nicht). Du hast 64MB frei, brauchst 128KB, aber der größte zusammenhängende Bereich ist nur 64KB groß!
Hä, was meinst Du? Was hat die konkrete interne Speicherverwaltung im OS-Kernel damit zu tun wenn das OS beim Start prüft ob die Größe des benutzten physischen Adressraums für das OS im grünen Bereich liegt?

Ich würde/werde für jede Architektur nen anderen HAL schreiben.
Willst Du damit sagen das Deiner Meinung nach die Speicherverwaltung des OS-Kernels in den HAL gehört? Das erscheint mir persönlich doch etwas arg seltsam. Ich kenne im Embedded-Umfeld einige OSe die auf mehr als 10 verschiedenen CPU-Architekturen laufen und diese CPU-Architekturen haben oft nicht viel mehr gemeinsam als das der virtuelle Speicher mit Hilfe von klassischem Paging gemanaged wird. Wie z.B. die PT-Einträge aufgebaut sind oder wie groß die Pages sind kann sich unterschieden aber das wird nur mit einer CPU-Architektur-spezifischen .h-Datei geregelt und ansonsten ist der Code für die Speicherverwaltung immer der selbe. Die Basis-Mechanismen von Flat-Memory (also die Wirkungsweise von Paging) sind auf allen real existierenden CPUs so enorm ähnlich das es sich einfach nicht lohnt dafür unterschiedlichen Code zu schreiben. Es ist doch auch relativ egal ob die Pages 4kB oder 8kB groß sind oder ob ein x-stufiges Paging-Directory in Hardware benutzt wird oder ob das per SW emuliert wird.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 07. January 2012, 16:25
Zitat von: erik
Wo widerspricht sich das?
Naja, ich meine wozu? Unter 32bit kommst du ja auch nicht auf die Idee bei einer 2/2 Aufteilung, bei mehr als 2GB RAM ne Fehlermeldung zu schmeißen "Too much Memory". Ne Warnung könnte ich noch im höchstfall aktzeptieren, aber ne Fehlermeldung (was für mich Abbruch bedeutet)?!

Zitat von: erik
An der selben Stelle im Boot-Code sollte auch noch eine Abfrage sein ob mindestens X MBytes an physischen RAM vorhanden sind damit das OS nicht schon beim Booten abstürzt.
Das ist übrigens nen sehr guter Hinweis (ob mindestens so viel Speicher vorhanden ist, dass das OS läuft) und ich habe schon einige Hobby OS´e gesehen die das nicht haben sondern einfach hängen bleiben.

Zitat von: erik
Hä, was meinst Du? Was hat die konkrete interne Speicherverwaltung im OS-Kernel damit zu tun wenn das OS beim Start prüft ob die Größe des benutzten physischen Adressraums für das OS im grünen Bereich liegt?
Sorry, das bezog sich auf das 1:1 Mapping im Kernel.

Zitat von: erik
Willst Du damit sagen das Deiner Meinung nach die Speicherverwaltung des OS-Kernels in den HAL gehört?
Kann sein das wir aneinander vorbei geredet haben, aber mir ging es darum, das ich vorhabe für jede Architektur nen extra Kernel zu haben, ohne Präprozessor Zeugs. Das dort gemeinsam genutzter Code ist, sollte klar sein (z.B. VMM und PMM, da ich immer von einer MMU also Paging ausgehe), aber ich werde für jede Architektur nen neuen HAL schreiben, weil es mMn keinen Sinn macht das Interface so allgemein zu halten das es auf wirklich jeder Architektur läuft. Was dann nach außen (was der Kernel also an Syscalls anbietet) sichtbar ist, dass wird überall gleich sein, nur die Implementierung wird eine andere Sein.

Mein Kernel ist im Moment z.B. verdammt stark auf x86 ausgerichtet und die Abläufe und Hardware-Initialisierung würde unter ARM so nicht umsetzbar sein. Alleine schon weil es unter ARM nen anderes Interrupt Konzept gibt.

Zitat von: erik
Es ist doch auch relativ egal ob die Pages 4kB oder 8kB groß sind oder ob ein x-stufiges Paging-Directory in Hardware benutzt wird oder ob das per SW emuliert wird.
Ich bin mir nicht mehr sicher, aber der Linux-Kernel macht sowas in der Art (Software-Emulation der Paging-Hierarchie) und da bin ich absolut dagegen. Die "paar" Zeilen Code kann man ruhig richtig auf die Hardware anpassen.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 07. January 2012, 21:10
Hallo,


Unter 32bit kommst du ja auch nicht auf die Idee bei einer 2/2 Aufteilung, bei mehr als 2GB RAM ne Fehlermeldung zu schmeißen "Too much Memory". Ne Warnung könnte ich noch im höchstfall aktzeptieren, aber ne Fehlermeldung (was für mich Abbruch bedeutet)?!
Ob Du es glaubst oder nicht, in meinem OS habe ich geplant in der 32 Bit-Version nicht mehr als 2 GB RAM zuzulassen. Mein Problem ist aber das ich in den 4 GB physischen Adressraum alles drin habe, alle Segmente aller Prozesse, der Kernel, sämtliche HW und dann brauch ich noch Reserve für den virtuellen Auslagerungsbereich wo die Segmente hin kommen wenn sie fragmentiert sind also Paging aktiv ist. Auf dem normalen x86-PC wird bei mehr als 2 GB RAM auch selten nur noch mit den Features des 386 gearbeitet, oft ist da PAE im Spiel, so das es sich streng genommen gar nicht mehr um echte 32 Bit-Systeme handelt. All diese Tricks hab ich aber nicht, ich lege einfach fest das wenn der RAM zu groß ist um vernünftig mit reinen 32 Bit-Features verwaltet zu werden dann muss eben ein 64 Bit-System her. Wenn Du Dir den Long-Mode mal genau anschaust wird Dir schnell auffallen dass das auch kein echter 64 Bit-Mode ist sondern das dort der virtuelle Adressraum auf 48 Bit (12 + 4*9) beschränkt ist. Wimre ist bei den neuesten AMD- und Intel-Prozis der physische Adressraum auf 56 Bit beschränkt (was die Fähigkeiten des Paging angeht, was also auch auf eine Art PAE hinaus läuft und auch entsprechenden Würgereiz verursacht) aber die Interfaces nach draußen können oft deutlich weniger, z.B. Hypertransport nur 40 Bit. Von daher bin ich schon der Meinung das es aus heutiger Sicht für absehbare Zeit Okay ist wenn man festlegt das der benutzte physische Adressraum maximal ein Viertel des virtuellen Kernel-Space (was ja auch nur die Hälfte des gesamten virtuellen Adressraums ist) betragen darf und sich dafür alle möglichen Krücken spart, so wie damals zu reinen 32 Bit-Zeiten. Damit kommt man mit heutigen x86-64-CPUs immerhin bis 32 TB und davon ist der Durchschnitts-PC noch einige Jahre entfernt, und wenn es mal so weit ist dann taugt das heutige OS eh nicht mehr viel so dass das Versagen dann (in > 20 Jahren) durchaus verschmerzbar ist.

Im Endeffekt ist Deine Entscheidung, Teile der Daten die eigentlich im virtuellen Kernel-Space liegen in den virtuellen Teil des jeweiligen Prozesses auszulagern, auch nur einer der möglichen Tricks um mit reinen 32 Bit-Mitteln möglichst dicht an 4 GB RAM heran zu kommen. Kann man so machen aber ich persönlich empfinde das als eher unelegant. Ich persönlich denke das auf einem Flat-Memory-System der physische RAM maximal ein Viertel des virtuellen Kernel-Space groß sein sollte damit man zuverlässig ohne Tricks auskommen kann. Dein Trick hat den Nachteil das Du nicht mehr im Kontext eines beliebigen Prozesses in der Verwaltung des virtuellen Adressraum eines anderen beliebigen Prozesses was ändern kannst, andere Tricks haben andere Nachteile, daher meine generelle Ablehnung solcher Tricks.

Kann sein das wir aneinander vorbei geredet haben
Oh ja, es ging doch eigentlich darum das Du eine austauschbare Speicherverwaltung für Deinen Micro-Kernel möchtest und ich der Meinung bin das die Speicherverwaltung in einem Micro-Kernel so zentral ist dass das Austauschen keinen Sinn ergibt. Klar muss man bestimmte Dinge hinter einem HAL verstecken wenn das OS auf wirklich verschiedenen CPU-Architekturen laufen soll aber das ist doch gar nicht das Thema dieser Teil-Diskussion gewesen.

Ich bin mir nicht mehr sicher, aber der Linux-Kernel macht sowas in der Art (Software-Emulation der Paging-Hierarchie) und da bin ich absolut dagegen. Die "paar" Zeilen Code kann man ruhig richtig auf die Hardware anpassen.
Ich denke mit was anderem als einer Software-Abstraktion bekommt man so unterschiedliche CPU-Architekturen (was die konkrete Implementierung des Paging angeht) wie x86, x86-64, ARM und SPARC kaum unter einen Hut und da die Speicherverwaltung des Linux-Kernel deutlich mächtiger und umfangreicher als die eines typischen Micro-Kernel ist lohnt es sich IMHO durchaus da passend zu abstrahieren um die Speicherverwaltung immer gleich lassen zu können.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 07. January 2012, 21:22
Zitat von: erik
davon ist der Durchschnitts-PC noch einige Jahre entfernt, und wenn es mal so weit ist dann taugt das heutige OS eh nicht mehr viel so dass das Versagen dann (in > 20 Jahren) durchaus verschmerzbar ist.
Oh, oh, dass heißt doch wiederrum das es auch nicht schlimm ist, wenn irgendein Counter in 20 Jahren mal überläuft, ist doch verschmerzbar ;)

Zitat von: erik
Im Endeffekt ist Deine Entscheidung, Teile der Daten die eigentlich im virtuellen Kernel-Space liegen in den virtuellen Teil des jeweiligen Prozesses auszulagern, auch nur einer der möglichen Tricks um mit reinen 32 Bit-Mitteln möglichst dicht an 4 GB RAM heran zu kommen.
Ich wollte den Trick nutzen, um meine Limits für alle möglichen Ressourcen so hoch wie möglich zu setzen, auch wenn es praktisch wahrscheinlich keinen Sinn geben wird. Vorallem nicht da ja die Treiber ihren eigenen Adressraum haben und das nicht auch noch im Kernel sein muss.

Zitat von: erik
Oh ja, es ging doch eigentlich darum das Du eine austauschbare Speicherverwaltung für Deinen Micro-Kernel möchtest und ich der Meinung bin das die Speicherverwaltung in einem Micro-Kernel so zentral ist dass das Austauschen keinen Sinn ergibt.
Da sind wir halt wieder unterschiedlicher Meinung, aber ich habe das ganze soweit abstrahiert, dass ich einfach mal um die Performance verschiedener Methoden zu testen, nur den neuen Allocator nehmen muss und 2 Funktionsaufrufe (valloc() und vfree()) anpassen muss. Ansonsten wird ja das meiste mit new (C++) gemacht und die überschriebenen Methoden müssten noch angepasst werden und schon habe ich mit verdammt wenig Aufwand nen anderen Allocator integriert. Das wäre bei deinem Konzept nicht möglich, da wäre viel mehr Aufwand für nötig.

Was das mit dem HAL betrifft, da ging es mir darum, dass ich einen neuen Kernel für jede Architektur schreiben möchte. Hat mit dem VMM erstmal nix zu tun, zumal der ja fast vollständig (Umsetzung des Pagings) übernommen werden kann.

Zitat von: erik
Ich denke mit was anderem als einer Software-Abstraktion bekommt man so unterschiedliche CPU-Architekturen (was die konkrete Implementierung des Paging angeht) wie x86, x86-64, ARM und SPARC kaum unter einen Hut und da die Speicherverwaltung des Linux-Kernel deutlich mächtiger und umfangreicher als die eines typischen Micro-Kernel ist lohnt es sich IMHO durchaus da passend zu abstrahieren um die Speicherverwaltung immer gleich lassen zu können.
An was denkst du da mit mächtiger? Ich denke mal die machen das nur weil es sich bei einem Monolithen halt nicht vermeiden lässt, ansonsten wird das zu aufwändig.

Da ist auch ganz eindeutig mMn ein MikroKernel im Vorteil. Vorallem geht durch die Software-Emulation ja Speicher und Performance verloren (was ja nun wirklich der worst-case ist).

Du bist gar nicht auf die Nachteile eines 1:1 Mappings eingegangen. Welche Vorteile bringt das eigentlich? Ich meine im Linux-Kernel werden ja ganz schöne Verrenkungen gemacht, damit es nutzen kann.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 07. January 2012, 22:09
Hallo,


Deine Latenz ist mal wieder beängstigend kurz. ;)

Oh, oh, dass heißt doch wiederrum das es auch nicht schlimm ist, wenn irgendein Counter in 20 Jahren mal überläuft, ist doch verschmerzbar ;)
Nein, Du versuchst hier Äpfel mit Birnen zu vergleichen. Es ist auf jeden Fall ein Unterschied ob eine SW nach 20 Jahren Laufzeit (auf immer dem selben Computer der dann auch 20 Jahre alt ist) abstürzt oder ob ein heutiges Programm auf einen Computer der erst in 20 Jahren überhaupt gebaut werden kann nicht mehr funktioniert. Ersteres kann in einer Katastrophe enden wogegen letzteres ein normales Phänomen des technischen Fortschritts darstellt und eben grundsätzlich nicht zu einer Katastrophe führen kann weil diese unheilige Konstellation aus alter SW und neuem Computer erst gar nicht anläuft so das erst gar keine kritischen Tasks drauf laufen können. Es wäre IMHO auch ein Bug wenn ich einen heutigen Computer mit heutiger SW als tauglich teste, das ganze dann für 20 Jahre in den Schrank packe und wenn ich das irgendwann mal brauche es plötzlich nicht mehr geht. Aber eine neue Zusammenstellung muss immer erst getestet werden bevor man damit kritische Aufgaben erledigen will.

Meiner Meinung nach wäre es deutlich schlimmer wenn die alte SW auf dem neuen Computer ohne sichtbare Warnung o.ä. anläuft aber dann irgendwann einfach abstürzt weil sie mit dem neuen Computer eben doch nicht gescheit umgehen kann, da ist mir eine klare Fehlermeldung deutlich lieber, oder?

Ich wollte den Trick nutzen ....
Schon klar, aber dieser Trick kostet Dich was und da musst Du erst mal überlegen ob das Preis-Leistung-Verhältnis stimmt.

Das wäre bei deinem Konzept nicht möglich, da wäre viel mehr Aufwand für nötig.
Ja, aber bei meinem Kernel dürfte die Speicherverwaltung (vor allem weil da Dinge wie das Defragmentieren usw. mit reinspielen) die zentrale Hauptkomponente des Kernels sein so das wenn ich das austauschen wollte das ich denn eh mehr als 50% des Quell-Codes tausche und da muss ich dann ehrlich sagen das es IMHO Quatsch ist wenn der Schwanz mit dem Hund wedelt.

An was denkst du da mit mächtiger? Ich denke mal die machen das nur weil es sich bei einem Monolithen halt nicht vermeiden lässt, ansonsten wird das zu aufwändig.
So weit ich weiß ist der Heap im Linux-Kernel (also kmalloc/kfree) durchaus sehr leistungsfähig und flexibel, natürlich ist das auch ein Zwang des Monolithen weil da ja mehr als eine kleine Hand voll an verschiedenen Objekt-Größen vorkommen und die HW-Treiber ja noch mal zusätzliche Anforderungen haben (was beides bei einem Micro-Kernel nicht zutrifft).

Du bist gar nicht auf die Nachteile eines 1:1 Mappings eingegangen. Welche Vorteile bringt das eigentlich?
Der Nachteil des 1:1 Mappings ist ganz klar das man einen, im Verhältnis zum physischen Speicher, recht großen virtuellen Kernel-Space benötigt bzw. andersherum das der maximale physische Speicher signifikant kleiner sein muss als der virtuelle Kernel-Space. Der Vorteil ist das man alle PDs usw. problemlos modifizieren kann ohne irgendwelche Verrenkungen unternehmen zu müssen, alles was irgendwie in den Kernel gehört ist auch immer, von jedem Kontext aus, im Kernel-Space erreichbar. Den Teilbereich des virtuellen Kernel-Space wo der physische Speicher 1:1 gemappt wird könnte man sogar statisch festlegen so das man hier auch keine dynamischen Adressen o.ä. benötigt. Mir persönlich wäre das genug damit ich mich bei einem Flat-Memory-OS genau dafür entscheiden würde. Aber es wäre ja auch langweilig wenn jeder seine Entscheidungen so treffen würde wie ich das zu tun pflege.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 07. January 2012, 22:17
Zitat von: erik
Den Teilbereich des virtuellen Kernel-Space wo der physische Speicher 1:1 gemappt wird könnte man sogar statisch festlegen so das man hier auch keine dynamischen Adressen o.ä. benötigt. Mir persönlich wäre das genug damit ich mich bei einem Flat-Memory-OS genau dafür entscheiden würde. Aber es wäre ja auch langweilig wenn jeder seine Entscheidungen so treffen würde wie ich das zu tun pflege.
Damit gibst du ja den großen Vorteil von Paging auf nämlich das Umgehen der Fragmentierung des physischen Speichers.

Das große Problem welches der Linux-Kernel halt hat, ist wie mein Bsp. von weiter oben, man hat 64MB freien RAM, der Kernel braucht 128KB zusammenhängenden freien Speicher, aber es gibt nur noch 64KB zusammenhängenden freien Speicher. Das ist doch absurd und sowas willst du?
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 07. January 2012, 22:50
Hallo,


Damit gibst du ja den großen Vorteil von Paging auf nämlich das Umgehen der Fragmentierung des physischen Speichers.
Da hast Du mich wohl miss verstanden. Ich meine nicht das der Kernel wirklich in dem 1:1 gemappten Teil selber lebt sondern der Kernel benutzt den Rest seines virtuellen Kernel-Space (deshalb darf der physische Speicher nur einen Teil des Kernel-Space belegen) so wie alle anderen Kernel auch, er nutzt nur den 1:1 Teil um darin z.B. die PDs zu manipulieren. In jedem Prozess-Descriptor benötigt man doch die physische Adresse des jeweiligen PD-Roots, die kommt ja schließlich auch ins CR3, und wenn man da einfach die statisch festgelegte virtuelle Start-Adresse des 1:1 Bereichs drauf addiert kann man das gesamte PD manipulieren wie man will (die enthaltenen physischen Adressen auf die untergeordneten Tabellen-Ebenen kann man wieder einfach mit einer Addition in eine gültige virtuelle Kernel-Space-Adresse umwandeln). Da alle Prozess-Descriptoren im normalen virtuellen Kernel-Space liegen (und damit aus jedem Kontext erreichbar sind) kann man auch immer an jedem beliebigen PD was ändern. So beliebte Tricks wie das der letzte Eintrag im Root-PD auf sich selbst zeigt damit in den letzten 4MB das PD und alle PTs enthalten sind ist damit hinfällig, dieser Trick hat ja auch wieder den Nachteil das damit immer nur das aktuelle PD manipulierbar ist.

Was Du immer mit Deinem zusammenhängen Speicher willst verstehe ich nicht. Mir fällt auf einem aktuellen PC mit einem Flat-Memory-OS absolut kein Grund ein physisch zusammenhängenden Speicher zu benötigen, nebst dessen dass das IMHO nichts mit der konzeptionellen Aufteilung des virtuellen Kernel-Space zu tun hat.


Grüße
Erik
Titel: Re: IPC - Popup-Threads
Beitrag von: FlashBurn am 08. January 2012, 08:40
Zitat von: erik
Was Du immer mit Deinem zusammenhängen Speicher willst verstehe ich nicht. Mir fällt auf einem aktuellen PC mit einem Flat-Memory-OS absolut kein Grund ein physisch zusammenhängenden Speicher zu benötigen, nebst dessen dass das IMHO nichts mit der konzeptionellen Aufteilung des virtuellen Kernel-Space zu tun hat.
Ich hänge mich da wahrscheinlich zu sehr an dem 1:1 Mapping und an der Art und Weise wie es in Linux umgesetzt ist auf. Die benutzen ja nen Buddy-Allocator und mappen auf x86 bis 768MB (glaub ich) 1:1. D.h. dann halt das du so nette Probleme wie das Bsp. was ich jetzt schon mehrmals gebracht habe, bekommst und deshalb mag ich das mit dem 1:1 Mapping nicht. Ich bin dabei aber auch davon ausgegangen, dass das dann wirklich 1:1 ist, also physisch == virtuell.

Ich bin mir nicht sicher, aber für nen Monolithen dürfte das doch auch Probleme geben, wenn alle PDs gemappt sind und dann auch noch die ganze Hardware, da stößt du doch relativ schnell (vorallem heute) and die 1GB Grenze und dann würde eine 2/2 Aufteilung (wie meistens bei x86 Windows) ja wieder besser sein.
Titel: Re: IPC - Popup-Threads
Beitrag von: erik.vikinger am 08. January 2012, 16:00
Hallo,


ich wuste gar nicht das Linux größere Mengen Speicher 1:1 mappt. Wirklich mit virtuell == physisch? Das kann ich mir ehrlich gesagt nicht so gut Vorstellen, Linux benutzt doch auch einen Higher-Half-Kernel oder?
Sorry, das ich mich da unklar ausgedrückt habe, mit 1:1 meinte ich nicht virtuell == physisch sondern nur das der tatsächlich benutzte physische Adressraum (der ja kleiner sein muss als die Plattform eigentlich kann) irgendwo als ganzes lineares Stück im virtuellen Adressraum (in dem Teil der zum Kernel-Space gehört) zu finden ist.

Da kommt mir die Idee das wenn man einen Lower-Half-Kernel machen würde dann würde das sogar echt gehen, tät immerhin die Additionen ersparen und bei einem Monolithen würden sicher auch die enthaltenen Treiber profitieren wenn Sie ihre HW direkt mit der physischen Adresse ansprechen können ganz ohne Umrechnung o.ä., man müsste den virtuellen Adressraum einfach so aufteilen dass das unterste Viertel dem 1:1 Bereich gehört, das nächste Viertel wäre dann der normale Kernel-Space und die obere Hälfte wäre dann Prozess-spezifischer User-Mode. Ich denke das könnte richtig gut funktionieren aber ich mach ja gar kein Flat-Memory-OS.


Grüße
Erik