Grundlegende Einführung in die cgroup

Das Aufkommen eines neuen Konzepts muss seine Gründe haben, und cgroup stellt da keine Ausnahme dar. Es wurde ursprünglich von den Google-Ingenieuren Paul Menage und Rohit Seth [1] vorgeschlagen : Weil die Fähigkeiten der Computerhardware immer leistungsfähiger werden, um die Effizienz zu verbessern der Maschine kann es in denselben Run-Jobs mit unterschiedlichen Rechenmodellen auf einer Maschine verwendet werden. Anfangs war es nach Prozesscontainern benannt, später, weil Container mehrere Bedeutungen hat, kann es leicht zu Missverständnissen kommen, 2007 wurde es in Control Groups umbenannt und in den 2.6.24-Kernel integriert, es kann einschränken, aufzeichnen und isolieren die physischen Ressourcen, die von Prozessgruppen verwendet werden (z. B. CPU/Speicher/IO usw.) und die Priorität der Steuerung der Verwendung physischer Ressourcen Dieser Artikel bezieht sich hauptsächlich auf den Kernel-5.10-Quellcode, um eine grundlegende Einführung in cgroup zu geben.

1. Zusammensetzung der cgroup

Wir verwenden cgroup, um Ressourcen für Prozessgruppen zu verarbeiten, was untrennbar mit den folgenden Komponenten verbunden ist:

7269edef25c970b3fb0c321d74e69fbe.png

cgroupv1 kann mehrere Ebenen zulassen. Mit der Organisation von v1 gibt es keine Möglichkeit, die Ressourcensteuerung der Subsysteme zu entkoppeln, wenn die verwendeten Subsysteme an derselben Ebene angehängt sind, und einige Prozesse können von anderen Subsystemen beeinflusst werden. Daher erfordert V1 mehrere Organisationsebenen, und eine Ebene kann als Baum betrachtet werden, der wiederum als Wald betrachtet werden kann.

Darüber hinaus sind die Beziehungen zwischen Cgroup, Task, Subsystem und Hierarchie und deren Grundregeln wie folgt:

  1. Ein oder mehrere Subsysteme können derselben Hierarchie zugeordnet werden.

  2. Ein Subsystem kann nur dann an mehrere Hierarchien angehängt werden, wenn diese Hierarchien nur dieses Subsystem haben.

  3. Für jede von Ihnen erstellte Hierarchie kann eine Aufgabe nur in einer der Cgroups vorhanden sein, d. h. eine Aufgabe kann nicht in verschiedenen Cgroups derselben Hierarchie vorhanden sein, aber eine Aufgabe kann in mehreren Cgroups in verschiedenen Hierarchien vorhanden sein.

  4. Die vom Prozess erstellte untergeordnete Aufgabe (Aufgabe) befindet sich standardmäßig in derselben Kontrollgruppe wie die ursprüngliche Aufgabe, aber die untergeordnete Aufgabe darf in eine andere Kontrollgruppe verschoben werden.

1.1 Subsystem Einführung

Das Subsystem wird hauptsächlich zur Steuerung von Ressourcen verwendet. Da es sich um ein spezifisches Steuerungsmodul handelt, wird es separat eingeführt. Mit der Zunahme von Anforderungen und Funktionen gibt es die folgenden wichtigeren und häufiger verwendeten Subsysteme:

475be6438b74f62cc636874cb1b6ec3b.png

Durch das Extrahieren dieser Subsysteme durch Cgroup werden auch diese Ressourcenverwaltungsmodule wiederverwendet.Die Essenz besteht darin, Haken an diese Ressourcenverwaltungsmodule anzuhängen,um eine Ressourcenbegrenzung und Prioritätszuweisung zu realisieren.

1.2 Cgroup-Schlüsseldatenstruktur

Uns interessiert, wie Tasks und Cgroups zugeordnet werden, da das System mehrere Ebenen haben kann und jede Task auch durch mehrere Subsysteme eingeschränkt sein kann, sodass eine Task in mehreren Cgroups existieren kann und jede Cgroup auch mehrere Tasks steuert. Daher befinden sich Tasks und cgroups in einer Viele-zu-Viele-Beziehung. Um diese Beziehung aufzuzeichnen, können Sie mehr verknüpfte Listen hinzufügen, aber die Such- und Änderungseffizienz ist zu gering.Linux verwendet zwei Zwischendatenstrukturen, css_set und cgrp_cset_link, um diese Abbildung zu vervollständigen.

Stellen Sie sich vor, wenn ein Prozess einen untergeordneten Prozess klont und keine bestimmte Cgroup angibt, bleibt der standardmäßige untergeordnete Prozess in denselben Cgroups wie der Prozess, und die Gruppe von Prozessen, die dieselben Cgroups teilen, wird extrahiert und mit css_set identifiziert. jeder Prozess existiert nur in einem css_set, ein css_set kann mehrere Prozesse enthalten, alle css_sets werden durch eine Hash-Tabelle organisiert, wenn der Prozess zwischen cgroups migriert wird, weil css_set auf der Gemeinsamkeit von cgroups basiert, die erstellt werden, sodass css_set auch wiederverwendet werden kann.

Cgroup-Informationen im Prozess:

a42312e695f9f03c201ae90d90db6c3c.png

Mit css_set, obwohl derselbe Prozesstyp in ein css_set gelinkt wird, wird es immer noch ein Problem der Viele-zu-Viele-Zuordnung zwischen css_set und cgroup geben, aber die Anzahl von css_set wird geringer sein als die Anzahl von Tasks , cgrp_cset_link kommt Neu Die hinzugefügte dritte Tabelle kann die Effizienz von cgroup und css_sets erheblich verbessern, einander zu finden.

Gesamtverbindungsverhältnis:

3cbb4c971f24825b98624edac0250739.png

Darüber hinaus zeichnet css_set einerseits die Prozessinformationen im cset auf und pflegt auch die Informationen des Subsystems subsys (kurz css), das auch als Bindeglied zwischen beiden betrachtet werden kann.

css_set-Schlüsselmitglieder:

65c6b7661f09840507205b012045a67d.png

ec04b98cf9a813af5f83d93760344691.png

Schlüsselmitglieder der Cgroup:

efc228c190ff41e38eb5b7c97a6bc9ee.png

8aa23c4db4a95c5aa835f8adce0549ef.png

cgroup_subsys_state, das Schlüsselobjekt des Cgroup-Betriebs, einschließlich der Offenlegung von Dateien, bezogen auf den Betrieb des Subsystems.

Seine wichtigsten Mitglieder:

45f73833f52320e4beafaf8fe9be87ef.png

Das Subsystem cgroup_subsys enthält hauptsächlich die allgemeinen Operationsmethoden jedes Subsystems.

Schlüsselmitglieder:

ff2972002f3a63c203575ae86888bcd5.png

Das Beziehungsdiagramm jeder Datenstruktur von cgroup:

1674f152155992e33c18dadb829aa9e6.png

2. cgroup-Initialisierung

Die Cgroup-Initialisierung ist relativ einfach und hauptsächlich in zwei Schritte unterteilt, cgroup_init_early und cgroup_init.

2.1 cgroup_init_early

Da es sich in einem sehr frühen Stadium des Bootens befindet, erledigt es hauptsächlich die folgende Arbeit:

  1. Wie init_task initialisiert das System auch cgrp_dfl_root als cgroup_root der Standardhierarchie.In ähnlicher Weise gibt es auch ein init_css_set, um verwandte Tasks in der Init-Phase zu initialisieren. In diesem Stadium bleiben standardmäßig die vom Init-Prozess geforkten untergeordneten Prozesse in init_css_set hängen.

  2. Wenn es verwandte Subsysteme gibt, die von anderen Modulen in der Init-Phase verwendet werden müssen, wird die cgroup-Datenstruktur in Bezug auf das Subsystem erstellt, die Beziehung zwischen den verwandten ss/css/cgroup/css_set wird hergestellt und schließlich online_css aufgerufen werden, damit das CSS tatsächlich wirksam wird, aber noch nicht im Dateisystem gerendert wird, und das Subsys von init_css_set initialisiert.

2.2 cgroup_init

Die Initialisierung ist hier angekommen, vfs und sysfs wurden initialisiert, die Hauptarbeit:

  1. Rufen Sie cgroup_setup_root auf, um cgrp_dfl_root zu initialisieren, und erstellen Sie zugehörige Dateien, die cgroup Benutzern zur Verfügung stellt, da in der Standardhierarchie zugehörige Dateien im cgroup_base_files-Array unter /sys/fs/cgroup erstellt werden, und rufen Sie dann rebind_subsystems auf Das Subsystem ist nicht wirklich beteiligt.Die Bewegung verschiedener Hierarchien aktiviert keine verwandten CSS-Dateien und legt keine SS-bezogenen Dateien offen. Verbinden Sie dann alle vorhandenen css_sets mit der Root-Cgroup, schließlich befinden sie sich zu diesem Zeitpunkt alle unter der Standardhierarchie.

  2. Initialisieren Sie jedes in cgroup_subsys.h definierte Subsystem, siehe 2.1.

  3. Mounten Sie init_css_set in cgrp_dfl_root, damit Sie alle Prozesse in init_css_set durch cgrp_dfl_root hängen lassen können.

  4. Für jedes zu initialisierende Subsystem werden die dem Benutzerraum zugänglich zu machenden Dateien initialisiert und erzeugt.

  5. Da das Subsys von init_css_set initialisiert und geändert wird, führen Sie den Hash-Link in css_set_table erneut aus.

  6. Registrieren Sie die Dateisystemtypen cgroup und cgroup2.

  7. Erstellen Sie eine /proc/cgroups-Datei, um eine Übersicht über die aktuellen System-cgroups anzuzeigen. Beispiel Ubuntu: Nach dem Booten gibt es nur noch eine Hierarchie, in der 179 cgroups angelegt und 14 Subsysteme aktiviert sind.

cf83bf2dcd6c5c4ac1c44a2a386d16ef.png

3.Aufgabe zur Erstellung und Zuweisung von Gruppen

cgroup vfs basiert auf kernfs. Der Mount-Prozess verwendet hauptsächlich kernfs, um den Superblock und das Root-Verzeichnis zu initialisieren. Außerdem werden cgroupv1 und cgroupv2 unterschieden. v2 unterstützt den Thread-Modus, und es gibt nur eine "standardmäßige einheitliche Hierarchie". Aufgrund des Formunterschieds muss v1 eine Hierarchie finden oder erstellen, v2 jedoch nicht.Außerdem gibt es einige Unterschiede in der Parameterverarbeitung während des Mountens, auf die hier nicht näher eingegangen wird.

3.1 Cgroup-Erstellung

Nachdem das Mounten erfolgreich war, können Sie über mkdir im gemounteten Dateiverzeichnis eine Kontrollgruppe erstellen.

Der Hauptprozess ist wie folgt:

  1. Suchen Sie den übergeordneten Knoten der Cgroup und prüfen Sie, ob einige Einschränkungen der aktuellen Ebene die Anforderungen erfüllen können, hauptsächlich die Anzahl der Nachkommen und die Tiefenbegrenzung.

  2. Rufen Sie cgroup_create auf, um eine spezifische Initialisierung durchzuführen, initialisieren Sie das Refcnt, das seinen Lebenszyklus verwaltet, erstellen Sie das Verzeichnis der Kernfs, in dem es sich befindet, erben Sie den aktuellen eingefrorenen Zustand des übergeordneten Knotens, damit das Einfrieren automatisch wirksam werden kann, und verknüpfen Sie sich dann selbst in die Kinderliste des übergeordneten Knotens, was praktisch ist Erstellen Sie die Baumstruktur von cgroup, die später verwendet wird, um ihre Nachkommen zu durchlaufen. Da cgroup v2 in der Standardhierarchie möglicherweise aktiviert ist, wird seine subtree_control nicht initialisiert. Auf anderen Ebenen werden subtree_control und subtree_ss_mask der aktuellen cgroup und ihrer Nachkommen initialisiert.Zu den spezifischen Unterschieden zwischen den beiden siehe die vorherige Parametereinführung.

  3. Rufen Sie css_populate_dir auf, um gemeinsame cgroup-Dateien im aktuellen Verzeichnis zu erstellen.

  4. Erstellen Sie für jedes aktivierte Subsystem CSS und die Initialisierungsdatei des aktuellen Subsystems (dfl_cftypes

und legacy_cftypes, aber es wird basierend darauf erstellt, ob es in der Standardhierarchie ausgewählt ist), wenn Sie also manuell mkdir cgroup aufrufen, werden Sie viele automatisch erstellte Dateien sehen.

3.2 Aufgabe der Kontrollgruppe zuweisen

Hier sprechen wir kurz über den Thread-Modus, wir können nur Domänen-cgroups erstellen, aber wir können 'threaded

' Gehen Sie zur "cgroup.type"-Datei der aktuellen Kontrollgruppe, um die Kontrollgruppe zu einem Thread zu machen. Wenn die Kontrollgruppe zu einer Thread-Kontrollgruppe wird, kann sie nicht in eine Domain-Kontrollgruppe geändert werden. Nachdem er gethreadet wurde, ist der übergeordnete Node der Domänen-Cgroup in der Nähe für Ressourcenstatistiken verantwortlich und wird zum dom_cgrp der Cgroup mit Thread type ändert sich von domain zu For domain threaded, und wenn alle Nachkommen des übergeordneten Knotens gelöscht werden, wird er in domain wiederhergestellt.

Der Thread-Modus kann uns bei der Steuerung durch Gruppierung auf Thread-Granularität unterstützen, aber er muss sich in einer Thread-Domäne befinden.

Knoten wie „cgroup.procs“ und „tasks“ von cgroupv1, „cgroup.procs“ und „cgroup.threads“ von cgroupv2 können eine cgroup-Steuerung realisieren, indem sie spezifische Task-PIDs in die Knoten schreiben.

Am Beispiel von "cgroup.procs" sieht der spezifische Prozess wie folgt aus:

  1. Holen Sie sich die Ziel-Cgroup, der Sie zuweisen möchten, aus der Benutzereingabe. Da es im v2-Modus arbeitet, gibt es eine Unterscheidung zwischen Prozessen und Threads zur getrennten Steuerung.Der "cgroup.procs"-Knoten findet den Prozessgruppenleiter der auszuführenden Aufgabe und migriert dann alle Threads in der Prozessgruppe zu die Ziel-cgroup .

  2. Rufen Sie die Kontrollgruppe ab, in der sich die Aufgabe derzeit befindet, da sie sich in der Standardhierarchie befindet und die Suchmethode durch cset_group_from_root leicht verständlich ist.

  3. cgroup_attach_task führt die Hauptmigrationsaktion aus, wobei cgroup_migrate_add_src die Csets verknüpft, zu denen alle Tasks in der Thread-Gruppe gehören, mit der verknüpften Liste preloaded_src_csets der Datenstruktur mgctx, die den Migrationsprozess aufzeichnet.

  4. cgroup_migrate_prepare_dst nimmt zuerst das Quell-CSet aus der verknüpften Liste preloaded_src_csets heraus, überlagert und migriert die entsprechende Ziel-CGroup, um das Ziel-CSet zu erhalten, und zeichnet dann die entsprechende Beziehung zwischen dem Quell-CSet und dem Ziel-CSet auf cset und das Ziel-cset sind inkonsistent, was bedeutet, dass der Zustand des Subsystems unterschiedlich ist, Sie müssen can_attach erneut ausführen und während der Migration Rückrufe anhängen und sie erneut in die Ressourcenverwaltung des Subsystems integrieren.

  5. cgroup_migrate_add_task migriert die cg_list der Aufgabe in der Thread-Gruppe in die verknüpfte Liste mg_tasks des cset, zu der sie gehört, und markiert die Aufgabe, um den Migrationsprozess zu starten. Verknüpfen Sie dann das cset mit der verknüpften Liste src_csets von mgctx.

  6. cgroup_migrate_execute ruft zuerst can_attach auf, um den geänderten Subsystemstatus zu erkennen, ruft dann das zu migrierende Cset aus der verknüpften Liste src_csets ab, durchläuft die Tasks in der verknüpften Liste mg_tasks im Cset und nimmt das entsprechende Ziel-Cset heraus, ruft css_set_move_task zum Migrieren auf, rcu_assign_pointer (task->cgroups, to); um die Migration abzuschließen.

4. Zusammenfassung

Dieser Artikel konzentriert sich auf die Beschreibung der cgroup-Datenstruktur und ihrer grundlegenden Konzepte. Da die Datenstruktur der cgroup etwas komplizierter ist, wird sie im Fokus beschrieben. Leser können sich wohler fühlen, sie gegen den Code zu lesen. Der Platz ist begrenzt und die spezifischen Cgroup-Subsysteme sind nicht betroffen, interessierte Studenten können dies nachholen.

Verweise:

【1】https://lwn.net/Articles/199643/

【2】Dokumentation/cgroup-v1/*

【3】Dokumentation/cgroup-v2.txt

【4】Kernel-5.10-Quellcode

0f9e50614436859341859a40cc056938.gif

Lange drücken, um Kernel Craftsman WeChat zu folgen

Linux Kernel Black Technology | Technische Artikel | Ausgewählte Tutorials

Ich denke du magst

Origin blog.csdn.net/feelabclihu/article/details/129095852
Empfohlen
Rangfolge