Cgroup-Abstraktionsebene

Android 10 und höher verwenden eine Kontrollgruppe (cgroup) Abstraktionsebene mit Aufgabenprofilen, mit denen Entwickelnde eine Menge (oder Sätze) von Einschränkungen, die auf einen Thread oder einen Prozess angewendet werden sollen. Das System den vorgeschriebenen Aktionen der Aufgabenprofile folgt, um eine oder mehrere geeignete Gruppen, über die Einschränkungen angewendet werden, und zugrunde liegende cgroup-Merkmale möglich sind, ohne dass dies Auswirkungen auf die höhere Software hat. Ebenen.

Cgroups

Cgroups bieten einen Mechanismus zum Aggregieren und Partitionieren von Aufgabensätzen (die aus Prozessen, Threads und allen ihren zukünftigen untergeordneten Elementen bestehen) in hierarchische Gruppen mit speziellem Verhalten. Android nutzt cgroups zur Steuerung und zum Systemressourcen wie CPU- und Arbeitsspeichernutzung und -zuweisung mit Unterstützung für Linux-Kernel cgroups v1 und cgroups v2.

Android 9 und niedriger

In Android 9 und niedriger enthielt das Initialisierungsskript init.rc eine Reihe von cgroups, deren Bereitstellungspunkte und Versionen. Auch wenn diese erwartete das Android-Framework, dass eine bestimmte Gruppe von cgroups Standorte mit einer bestimmten Versions- und Untergruppenhierarchie basierend auf dem . Dies schränkte die Möglichkeit ein, die nächste cgroup-Version auszuwählen, Ändern Sie die cgroup-Hierarchie, um neue Funktionen zu verwenden.

Android 10 und höher

Android 10 und höher verwenden cgroups mit Aufgabenprofilen:

  • Cgroup-Einrichtung: Entwickler beschreiben die Einrichtung von cgroups in ihren cgroups.json -Datei zur Definition von cgroups-Gruppen sowie deren Bereitstellungsspeicherorten und -attributen. Alle cgroups werden in der Early-init-Phase der Initialisierung bereitgestellt. .
  • Aufgabenprofile. Diese stellen eine Abstraktion bereit, die die erforderlichen von den Details ihrer Implementierung. Das Android-Framework wendet die in der task_profiles.json-Datei beschriebenen Aufgabenprofile mithilfe der SetTaskProfiles- und SetProcessProfiles-APIs auf einen Prozess oder Thread an. Diese APIs gibt es nur für Android 11 und höher.

Um Abwärtskompatibilität zu gewährleisten, werden die Legacy-Funktionen set_cpuset_policy, set_sched_policy und get_sched_policy bieten dieselbe API und Funktionalität. aber ihre Implementierung wurde geändert, um Aufgabenprofile zu verwenden. Neue Verwendung Fälle, in denen AOSP empfiehlt, anstelle der Legacy-APIs neue Aufgabenprofile zu verwenden set_sched_policy.

Cgroups-Beschreibungsdatei

Cgroups werden in der cgroups.json beschrieben -Datei unter <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ gespeichert. Jeder für die Verarbeitung Verantwortliche wird in einem Unterabschnitt beschrieben und muss mindestens die folgenden Anforderungen erfüllen:

  • Name, definiert im Feld Controller.
  • Der im Feld Pfad definierte Bereitstellungspfad.
  • Mode, UID (Nutzer-ID) und GID (Gruppen-ID), die den Eigentümer und Zugriffsmodi für die Dateien unter diesem Pfad (alle optional).
  • Optional. Legen Sie diesen Wert auf true fest, damit das System die Bereitstellung ignorieren kann. Fehler, der durch einen cgroup-Controller verursacht wird, dessen Bereitstellung vom Kernel nicht unterstützt wird.

Beispiel für eine cgroups.json-Datei

Im Beispiel unten sehen Sie Beschreibungen für cgroup v1 (Cgroups) und cgroup v2. (Cgroups2) Verantwortlichen mit ihren jeweiligen Pfaden.

{
  "Cgroups": [
    {
      "Controller": "cpu",
      "Path": "/dev/cpuctl",
      "Mode": "0755",
      "UID": "system",
      "GID": "system"
    },
    {
      "Controller": "memory",
      "Path": "/dev/memcg",
      "Mode": "0700",
      "Optional": true
    }
  ],
 "Cgroups2": {
   "Path": "/sys/fs/cgroup",
   "Mode": "0755",
   "UID": "system",
   "GID": "system",
   "Controllers": [
     {
       "Controller": "freezer",
       "Path": ".",
       "Mode": "0755",
       "UID": "system",
       "GID": "system"
     }
   ]
 }
}

Diese Beispieldatei enthält zwei Abschnitte, Cgroups zur Beschreibung von cgroup v1. Controller) und Cgroups2 (zur Beschreibung der cgroup v2-Controller). Alle Controller in der cgroups v2-Hierarchie werden am selben Ort bereitgestellt. Daher hat der Abschnitt Cgroups2 einen eigenen Pfad, einen eigenen Modus, eine eigene UID und GID-Attribute zur Beschreibung des Standorts und der Attribute für das Stammverzeichnis des Hierarchie. Das Attribut Pfad für Controllers unter Cgroups2 ist relativ zu diesem Stammpfad. Unter Android 12 und höher können Sie eine cgroup definieren Controller, der mit Pfad und Modus als "Optional" angegeben ist indem Sie ihn auf true setzen.

Die Datei cgroups.json wird im Rahmen des Init-Prozesses in der frühen Init-Phase geparst und die cgroups werden an den angegebenen Speicherorten bereitgestellt. Um später für die cgroup-Bereitstellungsstandorte verwenden Sie die API-Funktion CgroupGetControllerPath.

Datei mit Aufgabenprofilen

Die Datei task_profiles.json befindet sich unter <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Beschreiben Sie damit bestimmte Aktionen, die auf einen Prozess oder einen Diskussions-Thread. Einem Profilnamen ist eine Reihe von Aktionen zugeordnet, der in SetTaskProfiles- und SetProcessProfiles-Aufrufe zum Aufrufen von Profilaktionen.

Beispieldatei „task_profiles.json“

{
  "Attributes": [
    {
      "Name": "MemSoftLimit",
      "Controller": "memory",
      "File": "memory.soft_limit_in_bytes"
    },
    {
      "Name": "MemSwappiness",
      "Controller": "memory",
      "File": "memory.swappiness"
    }
  ],
  "Profiles": [
    {
      "Name": "MaxPerformance",
      "Actions" : [
        {
          "Name" : "JoinCgroup",
          "Params" :
          {
            "Controller": "schedtune",
            "Path": "top-app"
          }
        }
      ]
    },
    {
      "Name": "TimerSlackHigh",
      "Actions" : [
        {
          "Name" : "SetTimerSlack",
          "Params" :
          {
            "Slack": "40000000"
          }
        }
      ]
    },
    {
      "Name": "LowMemoryUsage",
      "Actions" : [
        {
          "Name" : "SetAttribute",
          "Params" :
          {
            "Name" : "MemSoftLimit",
            "Value" : "16MB"
          }
        },
        {
          "Name" : "SetAttribute",
          "Params" :
          {
            "Name" : "MemSwappiness",
            "Value" : "150"

          }
        }
      ]
    }
  ]
  "AggregateProfiles": [
     {
       "Name": "SCHED_SP_DEFAULT",
       "Profiles": [ "TimerSlackHigh", "MaxPerformance" ]
     },
     {
       "Name": "SCHED_SP_BACKGROUND",
       "Profiles": [ "LowMemoryUsage" ]
     }
}

Weisen Sie bestimmten cgroup-Dateien Namen als Einträge in der Liste Attribute zu. Jeder Eintrag enthält Folgendes:

  • Das Feld Name gibt den Namen des Attributs an.
  • Das Feld Controller verweist auf einen cgroup-Controller aus dem cgroups.json. -Datei mit ihrem Namen.
  • Im Feld Datei wird eine bestimmte Datei unter diesem Controller angegeben.

Attribute sind Verweise in Aufgabenprofildefinitionen. Außerhalb der Aufgabe Profilen, verwenden Sie sie nur dann, wenn das Framework direkten Zugriff darauf erfordert. und der Zugriff kann nicht mithilfe von Aufgabenprofilen abstrahiert werden. In allen anderen Fällen Aufgabenprofile verwenden; Sie ermöglichen eine bessere Entkopplung zwischen erforderlichem Verhalten und Details zur Implementierung.

Der Abschnitt Profile enthält Aufgabenprofildefinitionen, die Folgendes enthalten:

  • Das Feld Name definiert den Profilnamen.
  • Der Abschnitt Aktionen enthält eine Reihe von Aktionen, die ausgeführt werden, wenn das Profil angewendet. Jede Aktion hat Folgendes:

    • Im Feld Name wird die Aktion angegeben.
    • Der Abschnitt Params gibt eine Reihe von Parametern für die Aktion an.

Die unterstützten Aktionen sind in der Tabelle aufgeführt:

Aktion Parameter Beschreibung
SetTimerSlack Slack Durchhängendes Timer in ns
SetAttribute Name Ein Name, der auf ein Attribut aus dem Abschnitt Attribute verweist
Value Wert, der in die Datei geschrieben werden soll, die durch das benannte Attribut dargestellt wird
WriteFileFilePathPfad zur Datei
ValueWert, der in die Datei geschrieben wird
JoinCgroup Controller Name des cgroup-Controllers von cgroups.json
Path Ein Untergruppenpfad in der Hierarchie des cgroup-Controllers

Android 12 und höher bieten ein AggregateProfiles mit aggregierten Profilen, von denen jedes ein Alias für eine Reihe von einem oder mehreren Profilen. Die Definitionen für aggregierte Profile sehen so aus:

  • Das Feld Name gibt den Namen des aggregierten Profils an.
  • Profiles enthält die Namen der Profile, die im zusammengefassten Profil erstellen.

Wenn ein aggregiertes Profil angewendet wird, werden alle enthaltenden Profile ebenfalls automatisch angewendet. Aggregierungsprofile können sowohl einzelne Profile als auch andere Aggregierungsprofile enthalten, sofern keine Rekursionen (Profile, die sich selbst enthalten) vorhanden sind.

Init-Sprachbefehl „task_profiles“

Einen task_profiles-Befehl in der Android Init-Sprache ist für Android 12 und höher verfügbar, um die Aktivierung des Aufgabenprofils für einen bestimmten Prozess. Es ersetzt die writepid (in Android 12 eingestellt), mit dem ein zwischen cgroups. Der Befehl task_profiles bietet Flexibilität Ändern zugrunde liegender Implementierungen ohne Auswirkungen auf die oberen Layer. Im Im Beispiel unten führen diese beiden Befehle praktisch denselben Vorgang aus:

  • writepid /dev/cpuctl/top-app/tasks

    In Android 12 eingestellt; wird zum Schreiben der PID verwendet der aktuellen Aufgabe in die Datei /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    Verbindet den aktuellen Prozess mit der Top-App-Gruppe unter „cpu“ Controller (cpuctl), was dazu führt, dass die PID des Prozesses dev/cpuctl/top-app/tasks.

Verwenden Sie immer den Befehl task_profiles, um Aufgaben in cgroup-Hierarchien in Android 12 und höher. Es werden ein oder mehrere Parameter akzeptiert, die die Namen der in der task_profiles.json-Datei angegebenen Profile darstellen.

Aufgabenprofile auf API-Ebene

Unter Android 12 und höher können Sie Definitionen in den Standarddateien cgroups.json und task_profiles.json, entweder Ihre Änderung auf dem Android-API-Level basieren oder sie vom Anbieter selbst vornehmen lassen. -Partition an.

Um die Definitionen auf Grundlage des API-Levels zu überschreiben, müssen die folgenden Dateien auf dem Gerät vorhanden sind:

  • /system/etc/task_profiles/cgroups_<API level>.json

    Verwenden Sie dies für cgroups speziell für eine API-Ebene.

  • /system/etc/task_profiles/task_profiles_<API level>.json

    Verwenden Sie diese Option für Profile, die für eine API-Ebene spezifisch sind.

Zum Überschreiben der Definitionen aus der Anbieterpartition müssen die folgenden Dateien auf dem Gerät vorhanden sein:

  • /vendor/etc/cgroups.json
  • /vendor/etc/task_profiles.json

Wenn ein Attribut oder eine Profildefinition in diesen Dateien den gleichen Namen wie sich in der Standarddatei befindet, überschreibt die Dateidefinition (API- oder Anbieterebene) der vorherigen Definition. Definitionen auf Anbieterebene überschreiben API-Level-Definitionen. Wenn die neue Definition einen neuen Namen hat, oder Profile entsprechend der neuen Definition geändert.

Das Android-System lädt die Dateien cgroup und task_profile in dieser Reihenfolge:

  1. Standarddateien cgroups.json und task_profiles.json.
  2. Spezifische Dateien für API-Ebene, falls vorhanden.
  3. Anbieterpartitionsdateien, falls vorhanden.

Änderungen an der vorhandenen API

Android 10 und höher behalten die Funktionen set_cpuset_policy, set_sched_policy und get_sched_policy ohne Änderungen an der API. Unter Android 10 werden diese Funktionen libprocessgroup, die jetzt alle cgroup-bezogenen Funktionen enthält.

Der Header cutils/sched_policy.h ist zwar weiterhin vorhanden, aber um Unterbrechungen zu vermeiden vorhandener Code sorgt dafür, dass der neue Code ein neues processgroup/sched_policy.h enthält. Header.

Module, die eine dieser Funktionen verwenden, sollten eine Abhängigkeit vom libprocessgroup in ihr Makefile ein. Wenn für ein Modul kein anderes libcutils-Funktion, löschen Sie libcutils Bibliotheksabhängigkeit aus dem Makefile aus.

APIs für Aufgabenprofile

Die privaten APIs in processgroup/processgroup.h sind in der Tabelle definiert:

Typ API und Definition
bool SetTaskProfiles(int tid, const std::vector& profiles)
Wendet die in profiles angegebenen Aufgabenprofile mithilfe des Parameters tid auf den Thread an, der durch eine Thread-ID (tid) angegeben ist.
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles)
Wendet die in profiles angegebenen Aufgabenprofile auf den angegebenen Prozess an nach Nutzer- und Prozess-IDs mithilfe der Parameter uid und pid
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Gibt zurück, ob ein durch cgroup_name angegebener cgroup-Controller vorhanden ist. Bei true wird die Variable path auf den Stamm dieser cgroup festgelegt.
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Gibt zurück, ob ein mit attr_name angegebenes Profilattribut vorhanden ist. wenn true, legt die Variable path auf den Pfad der Datei fest, die mit dieses Profilattributs.
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Gibt zurück, ob ein mit attr_name angegebenes Profilattribut vorhanden ist. wenn true, legt die Variable path auf den Pfad der Datei fest, die mit dieses Profilattributs und dem Thread, der durch seine Thread-ID angegeben wird, mithilfe tid.
bool UsePerAppMemcg()
Gibt zurück, ob das System für die Verwendung von cgroups pro App-Arbeitsspeicher konfiguriert ist.