Was war der Grund für die Nicht-Präemptivität älterer Linux-Kernel?

15

Warum haben sich die ersten Linux-Entwickler für die Implementierung eines nicht präemptiven Kernels entschieden? Ist es, um die Synchronisation zu speichern?

Soweit ich weiß, wurde Linux in den frühen 90er Jahren entwickelt, als PCs einen einzelnen Prozessor hatten. Welchen Vorteil bietet ein nicht präemptiver Kernel in solchen PCs? Warum wird der Vorteil jedoch durch Multi-Core-Prozessoren gemindert?

Narden
quelle

Antworten:

25

Im Kontext des Linux-Kernels beziehen sich die Leute oft auf die Fähigkeit des Kernels, sich selbst zu unterbrechen - im Grunde genommen, Aufgaben zu wechseln, während Kernel-Code ausgeführt wird. Dies zuzulassen ist recht komplex, was wahrscheinlich der Hauptgrund dafür ist, dass es lange gedauert hat, bis der Kernel vorentleert werden konnte.

Anfangs konnte der meiste Kernel-Code sowieso nicht unterbrochen werden, da er durch die große Kernel-Sperre geschützt war. Diese Sperre wurde nach und nach aus immer mehr Kernel-Code entfernt, wodurch mehrere gleichzeitige Aufrufe des Kernels gleichzeitig möglich wurden (was mit zunehmender Verbreitung von SMP-Systemen immer wichtiger wurde). Aber das machte den Kernel selbst immer noch nicht vorentleerbar; das brauchte noch mehr entwicklung und gipfelte in dem PREEMPT_RTpatch-set, das schließlich im mainline-kernel zusammengeführt wurde (und in der lage war, die bkl ohnehin zu verhindern). Heutzutage kann der Kernel so konfiguriert werden, dass er je nach den gewünschten Durchsatz- und Latenzmerkmalen mehr oder weniger vorab entleerbar ist. Einzelheiten finden Sie in der zugehörigen Kernelkonfiguration .

Wie Sie den Erläuterungen in der Kernelkonfiguration entnehmen können, wirkt sich die Vorbelegung auf den Durchsatz und die Latenz aus, nicht auf die Parallelität. Auf Einzel-CPU-Systemen ist Pre-Emission immer noch nützlich, da Ereignisse mit kürzeren Reaktionszeiten verarbeitet werden können. Dies führt jedoch auch zu einem geringeren Durchsatz (da der Kernel Zeitschaltaufgaben ausführt). Durch die Vorbelegung kann eine bestimmte CPU in einem System mit einer oder mehreren CPUs schneller zu einer anderen Task wechseln. Der einschränkende Faktor bei Multi-CPU-Systemen ist nicht die Vorbelegung, es sind Sperren, große oder andere: Jeder Zeitcode, der eine Sperre erhält, bedeutet, dass eine andere CPU nicht die gleiche Aktion ausführen kann.

Stephen Kitt
quelle
11

Preemptive-Kernel bedeutet nur, dass es keine Big-Kernel-Sperre gibt .

Linux hatte von Anfang an präemptives Multitasking (dh Benutzercode war präemptibel) (meines Wissens war das allererste Linux 0.0.1, das von Linus auf den FTP-Server von funet hochgeladen wurde, bereits präemptives Multitasking). Wenn Sie beispielsweise mehrere Komprimierungs- oder Kompilierungsprozesse ausgeführt haben, wurden diese vom ersten Moment an parallel ausgeführt.

Im Gegensatz zu dem damals weit verbreiteten Win31. Wenn unter Win31 eine Aufgabe die CPU vom "Kernel" erhielt, war es standardmäßig ihre Verantwortung, zu bestimmen, wann die Steuerung an das Betriebssystem (oder an andere Aufgaben) zurückgegeben werden sollte. Wenn ein Prozess für diese Funktion keine spezielle Unterstützung hatte (was zusätzliche Programmierarbeit erforderte), wurden alle anderen Aufgaben während der Ausführung angehalten. Selbst die meisten in Win31 integrierten Basis-Apps funktionierten so.

Präventives Multitasking bedeutet, dass die Tasks keine Möglichkeit haben, die CPU nach Belieben zuzuweisen. Wenn stattdessen ihr Zeitfenster abläuft, entfernt der Kernel die CPU von ihnen. Daher kann in präventiven Betriebssystemen ein schlecht geschriebener oder schlecht funktionierender Prozess das Betriebssystem nicht einfrieren oder die Ausführung anderer Prozesse verhindern. Linux war immer präventiv für User-Space-Prozesse.

Die Big-Kernel-Sperre bedeutet, dass in einigen Fällen im Kernel-Bereich noch Sperren vorhanden sein können, die verhindern, dass andere Prozesse den geschützten Code ausführen. Zum Beispiel könnten Sie nicht montieren mehrere Dateisysteme gleichzeitig - wenn Sie mehrere montieren Befehle gab, wurden sie noch nacheinander ausgeführt, weil Montage Dinge , die Big Kernel Lock zuzuteilen erforderlich.

Um den Kernel präventiv zu machen, musste diese große Kernel-Sperre aufgehoben werden, dh der Mount und alle anderen Aufgaben mussten gleichzeitig ausgeführt werden können. Es war ein großer Job.

In der Vergangenheit wurde dies durch die zunehmende Unterstützung von SMP (Multi-CPU-Unterstützung) dringend erforderlich. Zum ersten Mal gab es wirklich Mainboards mit mehreren CPUs. Später wurden mehrere CPUs ("Kerne") in einen einzigen Chip integriert, heute sind die wirklich Multi-CPU-Mainboards bereits rar (sie sind typischerweise in teuren Serversystemen). Auch die wirklich Single-Core-Systeme (wo es nur eine einzige CPU mit einem einzigen Kern gibt) sind selten.

Daher lautet die Antwort auf Ihre Frage nicht "Was war der Grund für die Nicht-Präemptivität?", Weil sie immer präventiv war. Die eigentliche Frage ist, was die Ausführung des präventiven Kernels wirklich notwendig machte . Die Antwort lautet: das zunehmende Verhältnis der Systeme mit vielen CPUs und vielen Kernen.

Peterh: Setzen Sie Monica wieder ein
quelle
Ich habe Folgendes nicht wirklich verstanden :( Bis zur Kernel-Version 2.4 waren nur Benutzerprozesse preemptiv und der Kernel nicht preemptiv. Wie ich zuvor schon jemandem geantwortet habe, war der Grund wohl, die Arbeit an Synchronisations-Deadlocks zu sparen, die mit preemptiv passieren konnten Implementierung auf Single-Core-Prozess. Was denken Sie?
Narden
@Narden Ich weiß nicht, wo du es gelesen hast. Etwa bis 1.3 oder 2.0 konnte sich nur ein einzelner Prozess im Kernelraum befinden, selbst wenn mehrere Prozesse ausgeführt wurden. Diese Einschränkung wurde mit 2.0 grob beseitigt. Bis etwa 2.4 gab es ein Big Kernel Lock (dh das gleichzeitige Mounten mehrerer Dateisysteme funktionierte nicht).
Peterh - Wiedereinsetzung von Monica
@Narden Aber es ist kein kooperatives Multitasking, es wurde nie ein Prozess benötigt, um die CPU absichtlich an den Taskplaner zurückzugeben. Ja, der Grund für die BKL war wahrscheinlich, dass es eine Menge Arbeit ist, dies richtig zu machen: 1) Sperren müssen geteilt werden 2) Es sollten sperrenfreie Datenstrukturen verwendet werden, wenn es möglich ist 3) Geteilte Sperren führen zu Deadlocks / livelocks, das sind normalerweise besonders schmutzige, schwer zu behebende Fehler. Alle sollten gefunden und behoben werden. 4) Alle Treiber sollten auf die Änderungen in der Kernel-Core-API portiert werden.
peterh - Wiedereinsetzung von Monica
Ich habe es gelesen, als ich nach einer Antwort gesucht habe, und es wird auch als Information in einem von mir belegten Kurs mit dem Namen "Betriebssysteme" angegeben.
Narden
1
Die Big-Kernel-Sperre verhinderte, dass andere Threads in den Kernel eindringen, wenn einer im Kernel ausgeführt wurde. Es war nur ein Thread erlaubt, da der Kernel nicht von Anfang an auf symmetrisches Multiprocessing ausgelegt war. Ein vorbeugender Kernel bedeutet jedoch etwas anderes. Traditionell wurde der Ausführungskontext nur geändert, als der Kernel in den Benutzerbereich zurückkehrte. In einem vorbeugenden Kernel kann ein Thread in der Mitte des laufenden Kernel-Codes vorbeugt werden.
Johan Myréen
3

Dies ist keine technische Antwort, sondern eine historische Antwort auf die vom OP gestellte Frage : "Was war der Grund für die Nicht-Präemptivität älterer Linux-Kernel?"

(Ich nehme an, wie von @peterh in seiner Antwort und seinen Kommentaren erläutert, dass sich das OP unter "Nicht-Präemptivität" auf eine oder beide der Tatsachen bezieht, dass sich nur ein Benutzerprozess innerhalb des Kernels (in einer API) auf einem befindet time und / oder the Big Kernel Lock.)

Linus Torvalds war daran interessiert zu lernen, wie Betriebssysteme funktionieren, und er lernte, wie man eines schreibt. Sein Modell, seine Basis und seine anfängliche Entwicklungsumgebung waren Minix, ein vorhandenes Betriebssystem für Bildungszwecke (dh kein Produktionsbetriebssystem), das nicht kostenlos war (wie damals in Open Source - es war nicht kostenlos wie in Bier). entweder).

Also hat er einen Kernel ohne Vorkenntnisse geschrieben (das Big Kernel Lock, das in anderen Antworten erwähnt wurde), weil Sie es so machen, wenn Sie Ihr neues Betriebssystem schnell zum Laufen bringen wollen, zu Lernzwecken: Es ist auf diese Weise viel, viel einfacher. Ein Kernel, der die gleichzeitige Mehrfachprogrammierung von Benutzerprogrammen und Geräten unterstützt, ist schwierig genug - es ist äußerst schwierig, den Kernel selbst gleichzeitig auszuführen.

Wenn er gewusst hätte, wie beliebt / nützlich / wichtig Linux werden würde ... hätte er es wahrscheinlich genauso gemacht. (Nur IMO, ich habe keine Ahnung, was er tatsächlich denkt.) Weil du laufen musst, bevor du rennen kannst.

Und das blieb lange Zeit so, denn a) es gab noch viel zu tun, um Linux zu dem zu machen, was es heute ist (oder was es damals war), und b) es zu ändern, wäre ein großes schwieriges Unterfangen (wie in anderen Antworten erklärt).

Davidbak
quelle