Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: SuperPlus am 25. July 2011, 16:14

Titel: Disabled Interrupts im User Mode
Beitrag von: SuperPlus am 25. July 2011, 16:14
Hallo,

ich möchte Performancemessungen unter Linux im User Mode machen. Optimal wäre es, wenn während dieser Messungen die Interrupts ausgeschaltet wären. Dafür habe ich einen Trap Gate eingefügt.

ENTRY(cli_call)
     cli
     iret
END(cli_call)

Um in den Code zu springen verwende ich im User Mode den Befehl
int 0xe7

Die Interrupts sind aber immer noch aktiviert. Wird das Interrupt Flag beim Rücksprung automatisch gesetzt oder legt der Fehler in meinem Code?

Ich habe schon versucht die Interrupts mit dem VIF Flag zu deaktivieren. Dies hat aber auch nicht funktioniert. Wenn ich das Intel Manual richtig verstanden habe, ist der Interrupt Handler dafür zuständig das VIF Flag zu überprüfen und ich vermute Linux überprüft dieses Flag nicht.

Gibt es eine Möglichkeit im User Mode mit deaktivierten Interrupts zu arbeiten?

Grüße
SuperPlus
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: LittleFox am 25. July 2011, 16:18
Moin,

theoretisch dürfte es nicht funktionieren, sonst wäre Linux ein sehr unsicheres OS.
Wenn Interrupts deaktiviert sind funktioniert kein Multitasking mehr, die Uhr bleibt stehen und ähnliches Zeug.
Das ist der Grund warum cli und hlt im Usermode verboten sind.

Du musst also irgendwie eine andere Variante finden ;)

Grüße,
LittleFox

PS.: Willkommen im Forum :)
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: SuperPlus am 25. July 2011, 16:22
Danke für die schnelle Antwort.

Wenn ich einen Software Interrupt auslöse, dann bin ich doch im Kernel Mode. Dort lösche ich das IF und springe sofort wieder zurück in den User Mode. Dann müssten doch eigentlich die Interrupts deaktiviert sein.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: LittleFox am 25. July 2011, 16:27
Nein, dein Softwareinterrupt wird vom Kernel behandelt, nicht von deinem Programm. Oder schreibst du ein Modul? Wie es da ist weiß ich nicht.
Falls es ein Modul ist, den Rest einfach ignorieren ;)

Was der Kernel mit dem Interrupt macht kannst du im Sourcecode nachgucken.
Wird dein Handler überhaupt aufgerufen?

Grüße
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: SuperPlus am 25. July 2011, 16:36
Ich habe den Quellcode geändert und einen neuen Descriptor erstellt. Es ist so etwas wie ein eigener System Call.

Ich bin mir ziemlich sicher, dass der Code aufgerufen wird. Führe ich den Befehl "int 0xe7" bei einem normalen Linux aus, bekomme ich ein "Segmantaion Fault".
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 25. July 2011, 16:39
Hallo SuperPlus,


bei einem Interrupt wird der Status des Interuptflags auf dem Stack gesichert und am Ende wiederhergestellt. Wenn dann muss man nicht cli benutzen sondern den Wert auf dem Stack manipulieren. Ob Linux das überhaupt zulässt und ob dieser Handler nicht auf jeden Fall Teil des Kernels sein muss kann ich nicht wirklich beurteilen (raten würde ich nein und ja).

Und willkommen im Forum.


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: kevin am 25. July 2011, 17:03
Reicht für cli/sti nicht iopl() auf Ring 3?
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: SuperPlus am 25. July 2011, 17:09
Zitat
bei einem Interrupt wird der Status des Interuptflags auf dem Stack gesichert und am Ende wiederhergestellt.

Aha. Habe gerade noch mal ins Manual geguckt. Nach dem Sprung in den Interrupt Handler sieht das Stack Layout folgendermaßen aus:
EFLAGS
CS
EIP
Error Code
Ich habe nicht sehr viel Übung in Assembler. Wenn ich nun die EFLAGS ändern möchte würde ich das folgendermaßen machen:
pop eax ; EIP
pop ebx ; CS
pop ecx ; EFLAGS
or 0x20, eax ; setze IF
push ecx
push ebx
push eax
Könnte das so funktionieren?

Ich denke ich werden den Kernel mogen kompilieren und das mal testen.

Zitat
Reicht für cli/sti nicht iopl() auf Ring 3?
Nein, dadurch wird nur das virtuelle IF gelöscht und das hat bei mir nicht funktioniert. Unter einem Echtzeitlinux wie RTAI oder Xenomai könnte das aber vielleicht funktionieren. Dies wäre mein nächster Versuch.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: Jidder am 25. July 2011, 17:27
Du hast da eine 0 vergessen und die Operation muss auf ECX ausgeführt werden. Dann könnte es funktionieren.
pop %eax ; EIP
pop %ebx ; CS
pop %ecx ; EFLAGS
or $0x200, %ecx ; setze IF
push %ecx
push %ebx
push %eax

Ich würde es übrigens einfach so machen:
orl $0x200, 8(%esp)
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: Svenska am 25. July 2011, 20:38
Hallo,

bist du sicher, dass der Kernel - bei gelöschtem Interruptflag im Usermode - noch soweit funktioniert, dass ein Rücksprung möglich ist und er nicht abstürzt?

Ansonsten würde ich dir für Performancemessungen empfehlen, den betreffenden Usermodus-Task in der Priorität zu erhöhen (Echtzeitpriorität und "nice -20" für den Task) und für die Zeitstempel den TSC, soweit zuverlässig, zu benutzen. RDTSC geht auch im Usermodus.

Gruß,
Svenska
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: kevin am 25. July 2011, 20:55
Nein, dadurch wird nur das virtuelle IF gelöscht
Auf die Gefahr hin, eine blöde Frage zu stellen: Was ist denn ein virtuelles IF?
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 25. July 2011, 21:29
Auf die Gefahr hin, eine blöde Frage zu stellen: Was ist denn ein virtuelles IF?
Auf die Gefahr hin, eine blöde Antwort zu geben: RTFM!
SCNR

Ne, im Ernst, damit wird das IE-Flag virtualisiert so das die Programme denken sie manipulieren das tun es aber nicht in Wirklichkeit. Der Vorteil ist das man somit einige Exceptions sparen kann und bei wirklich kritischen Operationen muss dann eben der Kernel ein Bit im auf dem Stack gesicherten EFlag-Register prüfen. Aber sicherheitshalber trotzdem RTFM.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: Svenska am 25. July 2011, 21:38
Ich dachte, VIF ist das Interruptflag im VM86...
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: kevin am 25. July 2011, 21:46
VIF kenne ich auch, aber das ist ja offensichtlich nicht gemeint.

Ich würde auch sehr gern RTFM machen, aber dazu müsste ich halt wissen, wo nachschauen. Kapitelangabe oder so wäre hilfreich.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 25. July 2011, 22:06
Hallo,


ich dachte immer dass das VIF im Zusammenhang mit Bit 1 vom CR4 mehr kann als nur den VM86-Mode.
Aber falls ich da vorhin völligen Quatsch geschrieben hab dann tut mir das echt Leid, offensichtlich schätze ich meine x86-Kenntnisse für besser ein als sie tatsächlich sind. :(
Für RTFM bin ich aber Heute auch zu müde.


zum eigentlichen Thema:
Die Interrupts komplett zu deaktivieren müsste zwar theoretisch gehen und Linux sollte dabei eigentlich auch nicht abstürzen o.ä. aber die feine Art ist das IMHO trotzdem nicht. Was auch immer das eigentliche Problem ist, es sollte sich doch sicher auch eine andere Lösung finden lassen.


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: kevin am 25. July 2011, 22:34
Zitat
The processor only recognizes the VIF flag when either the VME flag or the PVI flag in control register CR4 is set and the IOPL is less than 3. (The VME flag enables the virtual-8086 mode extensions; the PVI flag enables the protected-mode virtual interrupts.)
IOPL hatte ich ja vorgeschlagen auf 3 zu setzen, die andere Variante geht also auch nicht.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: SuperPlus am 26. July 2011, 10:44
Hallo,

Zitat
Ich würde es übrigens einfach so machen:
orl $0x200, 8(%esp)
Danke für den Tipp. So habe ich es nun auch gemacht. Ich habe zwei Traps erstellt, einer löscht das IF und der andere setzt es wieder.
ENTRY(cli_call)
andl $0xFFFFFDFF, 8(%esp)
INTERRUPT_RETURN
END(cli_call)

ENTRY(sti_call)
orl $0x200, 8(%esp)
INTERRUPT_RETURN
END(sti_call)

Es scheint zu funktionieren. Zwischen den beiden Aufrufen ist jedenfalls das IF gelöscht und Linux reagiert nicht mehr. Allerdings tritt ein komischer Effekt in der Konsole auf. Diese produziert eine Menge Zeilenvorschübe.

Zitat
Ansonsten würde ich dir für Performancemessungen empfehlen, den betreffenden Usermodus-Task in der Priorität zu erhöhen
Bis jetzt habe ich das auch so gemacht. Ich habe dem Prozess einfach die höchste Priorität (99) gegeben und den Scheduler auf FIFO umgestellt. Um so länger der zu testende Code, um größer ist dann aber auch die Wahrscheinlichkeit, dass ein Interrupt auftritt. Ich möchte einfach sehen, wie groß der Unterschied zwischen den beiden Messmethoden ist.

Zitat
Ich würde auch sehr gern RTFM machen, aber dazu müsste ich halt wissen, wo nachschauen. Kapitelangabe oder so wäre hilfreich.
Im Intel Manual wird auf Kapitel "17.4 PROTECTED-MODE VIRTUAL INTERRUPTS" verwiesen. Aber wie gesagt, ich glaube es ist die Aufgabe des Interrupt Handler das VIF zu überprüfen.

Dank für eure Hilfe.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 26. July 2011, 10:58
Hallo,


also ob der Trap-Handler das IE-Flag löscht oder ob er dem User-Mode-Prozess das Recht gibt und dieser es selbst tut sollte in etwa auf das selbe Ergebnis hinaus laufen (wobei der zweite Weg mehr Risiken birgt da IOPL noch für andere Dinge ein Rolle spielt). Das der Linux-Kernel den EFlag-Wert auf dem Stack nicht prüft würrde ich persönlich Bug einstufen.

Trotzdem halte ich dieses Vorgehen für ungeschickt, auch wenn IMHO nichts dagegen spricht dass das zuverlässig funktionieren kann.
Von den zu erwartenden Nebenwirkungen wie stehen bleibende Uhr und Mauszeiger oder eventuellen Pufferüberläufen bei irgendwelchen HW-Komponenten (weil kein IRQ-Handler kommt um Daten abzuholen, hier sollte SMP helfen) mal abgesehen. So lange es sich nur um ein privates Experiment handelt ist das aber wohl schon in Ordnung.


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: kevin am 26. July 2011, 11:04
Im Intel Manual wird auf Kapitel "17.4 PROTECTED-MODE VIRTUAL INTERRUPTS" verwiesen. Aber wie gesagt, ich glaube es ist die Aufgabe des Interrupt Handler das VIF zu überprüfen.
Ich habe keine Ahnung, ob Linux das überhaupt benutzt, aber mit IOPL=3 spielt es jedenfalls keine Rolle.

Der Vorteil wäre halt, dass es iopl() schon gibt und man dafür den Kernel nicht patchen muss...
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: rizor am 27. July 2011, 21:44
Ich habe den Thread gerade nur ueberflogen, aber was genau moechtest du denn messen?
Ist es ein MultiCore Rechner?
Falls ja, kannst du das Mapping der IRQs aendern.
Du kannst die CPU-Affinitaet deiner Messung auf eine CPU legen, die keine IRQs behandelt.
Dann sollte das funktieneren.
Der einzige IRQ, der dann noch kommt ist der IRQ vom Timer.
Aber du kannst dem Scheduler sagen, dass alle Threads auf die CPU mit den IRQs gebunden werden und dein Messungsthread wird auf die andere CPU gebunden. Dann hast du schon echt gute Werte.
Oder du laesst dir vom Kernel einfach die reale CPU-Zeit geben.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 28. July 2011, 11:24
Hallo,


Oder du laesst dir vom Kernel einfach die reale CPU-Zeit geben.
Da würde ich erst mal nachprüfen wie diese ermittelt wird um deren Genauigkeit beurteilen zu können, ich vermute mal (ohne es zu wissen) das die nicht für reproduzierbare und präzise Performancemessungen taugt.


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: rizor am 28. July 2011, 17:41
Das ist kein Thema. Ist auf Nanosekunden genau. Das liegt daran, dass der Kernel in dem Fall die Zeiten zurück gibt, die in dem task-Struct des Kernels gespeichert sind. Die sind genau, da anhand dieser WErte auch die Scheduling-Entscheidungen getroffen werden. Das passt schon.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 28. July 2011, 18:19
Hallo,


Das ist kein Thema. Ist auf Nanosekunden genau....
Ach echt, das würde ich dann doch bezweifeln. Mit welchen Mechanismus sollen den auf der x86-Plattform Nanosekunden-Genau Zeiten ermittelt werden?


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: rizor am 28. July 2011, 19:06
Wenn ich mich recht entsinne, machen die das über den Clock-Counter. Der gibt ja die Takte an, die seit dem Boot gelaufen sind. Darüber soll das funktionieren. Die Rechnen intern mit Jiffies und nicht echten Zeiten. Das ganze soll dann recht genau umgerechnet werden können.
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 28. July 2011, 19:17
Hallo,


machen die das über den Clock-Counter.
Was ist das? Doch wohl nicht etwa die SW-Uhr (die läuft maximal mit der Genauigkeit der Timer-IRQs).

Und Jiffies sind eher eine rein mathematische Größe und kein Messwert.

Mit welchen Mechanismus sollen den auf der x86-Plattform Nanosekunden-Genau Zeiten ermittelt werden?


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: Jidder am 28. July 2011, 19:50
rizor meint den Time Stamp Counter, der die Taktzyklen zählt. Wenn man auf ein paar Details (Pipeline, dynamische Taktraten, Bugs) achtet, kann man damit die Zeit auf den CPU-Takt genau messen.

Nanosekunden gehen natürlich erst ab 1 GHz ^^
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 28. July 2011, 19:56
Hallo,


Das der Time Stamp Counter nur bedingt tauglich ist hatten wir hier doch schon mal ausführlich diskutiert. Spätestens wenn die CPU-Taktfrequenz geändert wird ist selbst die Mikrosekundenauflösung futsch. Der x86-Plattform fehlt ganz klar ein zentraler Timer (wirklich nur einer damit es keine Synchronisationsprobleme wie mit den TSCs bei SMP gibt) der mit hoher Frequenz arbeitet und sich in maximal 2 CPU-Takten auslesen lässt.


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: Svenska am 29. July 2011, 03:23
Ich würde rizors Aussage etwas freier interpretieren und sagen, dass er mit "nanosekundengenau" etwas meint, was erik vielleicht als "besser als mikrosekundengenau" bezeichnen würde. ;-)
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: erik.vikinger am 29. July 2011, 09:11
Hallo,


hm, selbst Mikrosekundengenau würde ich dem TSC nicht zutrauen wenn auch mal die CPU-Taktfrequenz geändert werden soll. Das ist nämlich kein deterministischer Vorgang, bis die PLL auf die neue Frequenz einrastet kann mal mehr und mal weniger Zeit vergehen in der der TSC steht und das sind mindestens etliche 10 bis etliche 100 Mikrosekunden (und der Jitter dürfte auch mindestens ein zweistelliger Mikrosekundenbetrag sein).


Grüße
Erik
Titel: Re:Disabled Interrupts im User Mode
Beitrag von: rizor am 29. July 2011, 19:25
Ich bin mir nicht sicher, ob es wirklich so ungenau ist.
Das würde bedeuten, dass Linux für seine Scheduling-Entscheidungen recht ungenaue Werte nimmt.
Das kann ich mir nicht wirklich vorstellen.
Vllt ist Nanosekunden genau übertrieben (habe ich nur mal irgendwo gelesen), aber damit sollte man trotzdem schon verlässliche Werte bekommen.