Warstwa abstrakcji Cgroup

Android 10 i nowsze używają grupy kontrolnej (cgroup) warstwa abstrakcyjna z profilami zadań, za pomocą których programiści mogą opisać (lub zestawów) ograniczeń, które mają być stosowane do wątku lub procesu. System wykonuje określone działania z profilu zadań i wybiera co najmniej 1 z nich. grup, dzięki którym są stosowane ograniczenia, oraz zmian podstawowy zestaw funkcji grupy cgroup można utworzyć bez wpływu na wyższe oprogramowanie warstw.

Informacje o grupach

Grupy dyskusyjne umożliwiają agregację i partycjonowanie zbiorów zadań (które składają się z procesów, wątków i wszystkich ich przyszłych elementów podrzędnych) w grupy hierarchiczne ze specjalistycznym zachowaniem. Android używa grup dyskusyjnych do kontrolowania i uwzględniania zasoby systemowe, takie jak wykorzystanie procesora i pamięci oraz przydział, oraz obsługa jądro Linuksa (cgroups w wersji 1); i cgroups w wersji 2.

Android 9 i starsze

W Androidzie 9 i starszych wersjach skrypt inicjowania init.rc zawierał zestaw dostępne grupy cgroups, ich punkty podłączania i wersje. Choć mogą to być platforma Androida wymagała istnienia określonego zestawu grup określonych lokalizacji z określoną hierarchią wersji i podgrup, na podstawie skrypt. Ograniczyło to możliwość wyboru następnej wersji grupy grup, która ma być używana, lub zmienić hierarchię grup dyskusyjnych, aby korzystała z nowych funkcji.

Android 10 lub nowszy

Android 10 i nowsze wersje używają grup dyskusyjnych z profilami zadań:

  • Konfiguracja grupy Cgroup. Deweloperzy opisują konfigurację grup dyskusyjnych w cgroups.json do zdefiniowania zestawów grup cgroups oraz ich lokalizacji i atrybutów podłączania. Wszystkie grupy Cgroups są montowane podczas wczesnych etapów inicjowania. proces tworzenia konta.
  • Profile zadań. Stanowią one abstrakcję, która oddziela wymagane od szczegółów jej implementacji. Struktura Androida stosuje profile zadań zgodnie z opisem w pliku task_profiles.json do za pomocą interfejsów API SetTaskProfiles i SetProcessProfiles. Te interfejsy API są dostępne tylko w Androidzie 11 i nowszych.

Aby zapewnić zgodność wsteczną, starsze funkcje set_cpuset_policy, set_sched_policy i get_sched_policy udostępniają ten sam interfejs API i funkcje, ale ich implementacja została zmodyfikowana, aby korzystać z profili zadań. Nowe zastosowania przypadki, gdy AOSP zaleca korzystanie z nowych interfejsów API profili zadań zamiast starszych set_sched_policy.

Plik z opisem Cgroups

Opis grup dyskusyjnych znajdziesz tutaj: cgroups.json znajduje się w folderze <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Każdy administrator został opisany w podsekcji i musi spełniać co najmniej te wymagania:

  • Nazwa zdefiniowana w polu Kontroler.
  • Ścieżka podłączenia zdefiniowana w polu Ścieżka.
  • Tryb, UID (identyfikator użytkownika) i GID (identyfikator grupy) opisujące właściciela i właściciela. tryby dostępu do plików w tej ścieżce (wszystkie opcjonalne).
  • Atrybut opcjonalny z ustawioną wartością true, aby system mógł zignorować podłączenie. błąd spowodowany przez kontroler Cgroup, który nie obsługuje podłączania jądra.

Przykładowy plik cgroups.json

Przykład poniżej zawiera opisy grup cgroup v1 (Cgroups) i cgroup v2 (Cgroups2) wraz z odpowiednimi ścieżkami.

{
  "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"
     }
   ]
 }
}

Ten przykładowy plik zawiera 2 sekcje: Cgroups (opisuje grupę cgroup v1) kontrolery) i Cgroups2 (opisuje kontrolery cgroup v2). Wszystkie kontrolery w hierarchii cgroups w wersji 2 są podłączone w tej samej lokalizacji. Dlatego sekcja Cgroups2 ma własne ścieżki, tryb, UID i GID opisuje lokalizację i atrybuty głównego katalogu w hierarchii. Atrybut Ścieżka elementów kontrolerów w grupie Cgroups2 ma wartość względem danej ścieżki głównej. W Androidzie 12 i nowszych możesz zdefiniować grupę grupową kontroler ze ścieżką i trybem określonym jako "Optional" ustawiając tę wartość na true.

Plik cgroups.json jest analizowany w ramach procesu inicjowania etapie, a grupy Cgroups są zamontowane w określonych lokalizacjach. Aby później uzyskać w lokalizacjach podłączenia grupy cgroup, użyj funkcji interfejsu API CgroupGetControllerPath.

Plik profili zadań

task_profiles.json znajduje się w folderze <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Służy do opisania konkretnego zestawu działań, które mają zostać zastosowane do procesu lub w wątku. Zestaw działań jest powiązany z nazwą profilu, która jest używana w Wywołania SetTaskProfiles i SetProcessProfiles służące do wywoływania działań profilu.

Przykładowy pliktask_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" ]
     }
}

Przypisz nazwy do konkretnych plików grupy cgroup jako pozycje na liście Atrybuty. Każda pozycja zawiera:

  • Pole Name (Nazwa) określa nazwę atrybutu.
  • Pole Kontroler odwołuje się do kontrolera grupy Cgroup z konsoli cgroups.json według nazwy.
  • Pole Plik zawiera nazwę konkretnego pliku podlegającego temu kontrolerowi.

Atrybuty to odwołania w definicjach profili zadań. Poza zadaniem profili, używaj ich tylko wtedy, gdy platforma wymaga bezpośredniego dostępu do tych profili i nie można wyodrębnić dostępu za pomocą profili zadań. We wszystkich innych przypadkach korzystać z profili zadań; pozwalają lepiej oddzielić wymagane zachowania szczegóły implementacji.

Sekcja Profile zawiera definicje profili zadań zawierające następujące elementy:

  • Pole Name (Nazwa) określa nazwę profilu.
  • Sekcja Działania zawiera listę działań wykonywanych, gdy profil jest zastosowano. Każde działanie obejmuje:

    • Pole Name (Nazwa) określa działanie.
    • Sekcja Parametry określa zestaw parametrów działania.

Obsługiwane działania są wymienione w tabeli:

Działanie Parametr Opis
SetTimerSlack Slack Zwolnienie licznika czasu w ns
SetAttribute Name nazwa odwołująca się do atrybutu z sekcji Atrybuty,
Value Wartość do zapisania w pliku reprezentowana przez nazwany atrybut
WriteFileFilePathścieżka do pliku
Valuewartość do zapisania w pliku
JoinCgroup Controller Nazwa kontrolera grupy Cgroup z cgroups.json
Path Ścieżka podgrupy w hierarchii kontrolera grupy

Android 12 i nowsze mają funkcję AggregateProfiles zawierająca profile zbiorcze, z których każdy jest aliasem dla zestawu co najmniej jednego profilu. Definicje profili zbiorczych składają się z tych elementów:

  • Pole Nazwa określa nazwę profilu zbiorczego.
  • W polu Profile znajduje się lista nazw profili uwzględnionych w profilu agregacji.

Po zastosowaniu profilu zbiorczego wszystkie profile zawierające go zostaną również automatycznie zastosowane. Profile zbiorcze mogą zawierać zarówno pojedyncze profile lub innych profili zbiorczych, o ile nie występują powtarzanie (profil obejmuje samą siebie).

polecenie języka init (task_profiles)

Polecenie task_profiles w języku Android Init jest dostępna na Androida 12 i nowsze wersje, aby ułatwić aktywacji profilu zadania dla określonego procesu. Zastępuje ona writepid (wycofane w Androidzie 12) użyte do migracji między grupami. Polecenie task_profiles zapewnia elastyczność i zmieniania podstawowych implementacji bez wpływu na górne warstwy. W Oto dwa polecenia, które pozwalają wykonać tę samą operację:

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

    Wycofany w Androidzie 12. Służył do zapisywania identyfikatora PID bieżącego zadania do pliku /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    Łączy bieżący proces z grupą najpopularniejszych aplikacji w sekcji „cpu” kontroler (cpuctl), co powoduje zapisanie identyfikatora PID procesu, dev/cpuctl/top-app/tasks

Zawsze używaj polecenia task_profiles do przenoszenia zadań w hierarchiach cgroup w Androida 12 lub nowszego, Akceptuje on co najmniej 1 parametr reprezentujący nazw profili określonych w pliku task_profiles.json.

Profile zadań na poziomie interfejsu API

W Androidzie 12 i nowszych możesz zmienić w domyślnych plikach cgroups.json i task_profiles.json, zarówno Opieranie zmian na poziomie interfejsu API Androida lub przekazywanie ich przez dostawcę partycji danych.

Aby zastąpić definicje na podstawie poziomu interfejsu API, musisz wykonać te pliki: na urządzeniu:

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

    Używaj w przypadku grup cgroups specyficznych dla poziomu interfejsu API.

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

    Używaj w przypadku profili specyficznych dla danego poziomu interfejsu API.

Aby zastąpić definicje z partycji dostawcy, te pliki muszą być obecny na urządzeniu:

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

Jeśli atrybut lub definicja profilu w tych plikach ma taką samą nazwę jak znajduje się w pliku domyślnym, definicja pliku (na poziomie interfejsu API lub dostawcy) zastępuje definicję poprzedniej definicji. Pamiętaj też, że definicje na poziomie dostawcy zastępują te zasady. Definicje na poziomie interfejsu API. Jeśli nowa definicja ma nową nazwę, to zestaw atrybuty lub profile zostaną uzupełnione o nową definicję.

System Android wczytuje pliki cgroup i task_profile w tej kolejności:

  1. Domyślna cgroups.json i task_profiles.json .
  2. Pliki dotyczące konkretnego poziomu interfejsu API (jeśli istnieją).
  3. Pliki partycji dostawców, jeśli istnieją.

Zmiany w obecnym interfejsie API

Android 10 i nowsze wersje zachowują funkcje set_cpuset_policy, set_sched_policy i get_sched_policy bez zmian w interfejsie API. Android 10 przenosi te funkcje libprocessgroup, który zawiera teraz wszystkie funkcje związane z grupami.

Mimo że nagłówek cutils/sched_policy.h nadal istnieje, aby uniknąć uszkodzenia istniejący kod pozwala upewnić się, że nowy kod zawiera nowe processgroup/sched_policy.h nagłówek.

Moduły, które używają dowolnej z tych funkcji, powinny dodawać zależność libprocessgroup bibliotekę do swojego pliku Makefile. Jeśli moduł nie używa żadnego innego kodu Funkcja libcutils, porzuć libcutils do biblioteki z pliku Makefile.

Interfejsy API profili zadań

Prywatne interfejsy API w processgroup/processgroup.h są zdefiniowane w tabeli:

Typ Interfejs API i definicja
bool SetTaskProfiles(int tid, const std::vector& profiles)
Stosuje profile zadań określone w profiles do wątku określonego przez identyfikator wątku (tid) za pomocą parametru tid.
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles)
Stosuje profile zadań określone w profiles do procesu określonego w procesie według użytkownika i identyfikatorów przetwarzania za pomocą parametrów uid i pid
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Zwraca informację, czy istnieje kontroler grupy Cgroup określony przez parametr cgroup_name. jeśli true, ustawia zmienną path na pierwiastek tej grupy grupowej
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Zwraca informację, czy istnieje atrybut profilu określony przez parametr attr_name. jeśli true ustawia zmienną path na ścieżkę pliku powiązanego z ten atrybut profilu.
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Zwraca informację, czy istnieje atrybut profilu określony przez parametr attr_name. jeśli true ustawia zmienną path na ścieżkę pliku powiązanego z tego atrybutu oraz do wątku określonego przez jego identyfikator wątku za pomocą funkcji parametr tid.
bool UsePerAppMemcg()
Zwraca informacje o tym, czy system jest skonfigurowany do używania grup pamięci cgroups dla poszczególnych aplikacji.