Das Problem das Du Pages bereits im Frei-Pool hast die aber eventuell noch in TLBs einiger/anderer CPUs drin sind muss aber gelöst werden indem Du alle TLBs löscht bevor die Pages in den Frei-Pool kommen. Das senden der IPIs und warten auf alle Antworten muss also in der Mitte von vmmUnmap() passieren und nicht erst hinterher.
So wie du dir das denkst funktioniert das bei mir nicht. Ich hatte doch mal ne vereinfachte Variante von meiner vmmUnmap/vmmMap geschrieben.
Die Pages landen ziemlich "spät" bis gar nicht im Frei-Pool. Die sind auch gar nicht das Problem, sondern das eine andere CPU auf Page A zugreift, da es so im TLB steht, aber inzwischen Page B an der virtuellen Adresse steht.
Diese Situation tritt natürlich sehr sehr selten auf.
Solange ich aus der vmmMap/vmmUnmap Funktion noch nicht rausbin, sind die Pages praktisch noch nicht in Verwendung. Also kann ich das TLB Löschen auch hinterher machen (aber ich gebe den Lock erst frei, wenn die Nachricht versendet ist).
Es ist halt wieder ne Performance-Frage, ich meine stell dir vor, es sollen 20 Pages geunmappt werden, da wäre es sehr schlecht wenn du auch 20 IPIs versendest und dann auch noch wartet müsstest bis die anderen CPUs ihr IPIs abgearbeitet haben!
Ich bestreite nicht das Du Dir Mühe gibst aber aus Deinen vergangenen Problembeschreibungen habe ich den subjektiven Eindruck gewonnen das Dir da etwas an Erfahrung fehlt und Du deswegen verschiedene Probleme nicht so deutlich/frühzeitig erkennst.
Richtig, an Erfahrung mangelt es mir, besonders was das Programmieren von Anwendungen betrifft. Meine Programmiererfahrung beschränkt sich leider nur auf das OS Programmieren.
Du solltest mal ganz klar definieren was ein Bug ist und dann Code schreiben der zur Laufzeit (in der Debug-Version) nach genau dieser Bedingung prüft. Mit diesem Weg kommst Du zu recht präzisen Debug-Meldungen, zumindest bin ich bis her damit recht gut gefahren.
Am Bsp. einer Deadlock wüsste ich nicht wie ich zur Laufzeit prüfen könnte das einer vorliegt. Das gemeine am Deadlock ist doch, du kannst ja nicht wissen ob der Lock halt gerade in Benutzung ist und bald wieder freigegeben wird oder ob der Besitzer des Lock gerade versucht den Lock zu bekommen den man selber inne hat!
Jedes mal wenn Du einen Deadlock hast musst Du die Ursache heraus finden und dann wird Dein Code mit jedem beobachteten Deadlock besser.
Und genau hier ist doch das Problem. Ich kann nur Bugs fixen die ich "nachstellen" kann (das ist das größte Problem von Bugs eines OSs). Ein Deadlock der nur sporadisch auftritt und nach keinem Muster zu "fangen" ist, wie willst du da raus bekommen, in welcher Lock jemand war und welche Lock er bekommen wollte.
Was ich damit sagen will, stell dir vor du hast ein tolles OS geschrieben und das wird halt ausgeführt (ohne Debug-Msgs) und das bleibt halt von Zeit zur Zeit an immer einer anderen Stelle hängen und du als Entwickler kannst die Situation nicht nachstellen. Das kann alles sein, von Hardware-Problem bis irgendein Lockingfehler der schwer zu finden ist.
Klar gibt es ein paar zusätzliche Schwierigkeiten aber die sind IMHO nicht unlösbar.
Von unlösbar redet ja auch keiner, nur schwierig zu lösen
Das stimmt doch gar nicht, man muss in der Design-Phase nur das nötige Maß an Umsicht walten lassen dann bringt Multithreading fast keine zusätzliche Komplexität mit sich.
Fairerweise muss man schon mal sagen, wer macht denn ne wirkliche Design-Phase (mal von dir und deiner Hardware abgesehen)?
Ich behaupte mal das selbst bei größeren Softwareprojekten nicht so viel vorher designt wird, sondern das dann alle drauflos programmieren und deswegen kommt es oft zu Problemen.
Und ich als Hobbyprogrammieren/Anfänger werde mich bestimmt nicht vorher hinsetzen und ein Design anfertigen. Denn dann würde ich heute noch immer keinen Kernel haben, weil ich mich mit Dingen beschäftigen würde, von denen ich keine Ahnung habe und ohne Praxis auch nie haben werde.
Wofür willst Du alle CPUs anhalten? Planst du noch andere Dinge für IPI?
Anhalten will ich sie nur im Falle einer Kernel-Exception (damit die nicht alle ne for(;
; Schleife abarbeiten) und wenn der PC runtergefahren wird. Ansonsten könnte man noch die Möglichkeit geben, CPUs zur Laufzeit "abzuschalten", aber wozu das gut sein soll weiß ich nicht.
Ich habe halt z.B. mit der Rendevouz-Funktion versucht mein IPI System möglichst nutzbar zu machen, keine Ahnung ob ich das später noch für was anderes als TSC synchronisieren nutzen werde.
Auch weiß ich nicht ob man je die Möglichkeit braucht das man eine IPI Nachricht an genau eine CPU (und eine bestimme) schicken können muss.
Mal von den TLB-Flushs abgesehen benötigt man IMHO auch bei x86 keinen unterbrechbaren Micro-Kernel.
Wenn du den Kernel mit einem GIANT_LOCK schützt brauchst du nichtmal dafür nen unterbrechbaren MikroKernel.