Android 10 i nowsze wersje używają warstwy abstrakcji grupy sterowania (cgroup) z profilami zadań, których deweloperzy mogą używać do opisywania zestawów ograniczeń do zastosowania w wątku lub procesie. Następnie system wykonuje określone działania w ramach profili zadań, aby wybrać co najmniej jedną odpowiednią grupę cgroup, w której są stosowane ograniczenia, oraz wprowadzić zmiany w podstawowym zbiorze funkcji cgroup bez wpływu na wyższe warstwy oprogramowania.
Grupy
Grupy Cgroups stanowią mechanizm służący do agregowania i dzielenia zbiorów zadań (które składają się z procesów, wątków i wszystkich ich przyszłych elementów podrzędnych) na grupy hierarchiczne o specjalnym zachowaniu. Android używa cgroups do kontrolowania zasobów systemu, takich jak wykorzystanie i przydzielanie procesora i pamięci, z obsługą cgroups w jądrze Linuxa w wersji 1 i cgroups w wersji 2.
Android 9 i starsze
W Androidzie 9 i starszych skrypt inicjalizacji init.rc
zawierał zestaw dostępnych grup, ich punktów montażowych i wersji. Chociaż można je zmienić, platforma Android oczekuje, że w określonych miejscach w zależności od skryptu będzie istniał określony zestaw grup. Ograniczało to możliwość wybrania następnej wersji cgroup lub zmiany hierarchii cgroup w celu korzystania z nowych funkcji.
Android 10 lub nowszy
Android 10 i nowsze korzystają z grup użytkowników z profilami zadań:
- Konfigurowanie grupy C. Deweloperzy opisują konfigurację grup cgroup w pliku
cgroups.json
, aby zdefiniować zestawy grup cgroup oraz ich lokalizacje i atrybuty. Wszystkie grupy są montowane na wczesnym etapie procesu inicjalizacji. - Profile zadań. Zapewniają one abstrakcję, która odłącza wymaganą funkcjonalność od szczegółów jej implementacji. Platforma Androida stosuje profile zadań zgodnie z opisem w pliku
task_profiles.json
do procesu lub wątku za pomocą interfejsów APISetTaskProfiles
iSetProcessProfiles
. (te interfejsy API są dostępne tylko na Androidzie 11 i nowszych).
Aby zapewnić zgodność wsteczną, funkcje poprzedniej wersji set_cpuset_policy
, set_sched_policy
i get_sched_policy
udostępniają ten sam interfejs API i te same funkcje, ale ich implementacja została zmodyfikowana, aby używać profili zadań. W przypadku nowych przypadków użycia AOSP zaleca używanie nowych interfejsów API profili zadań zamiast starszej funkcji set_sched_policy
.
Plik z opisem grup
Grupy C zostały opisane w pliku cgroups.json
znajdującym się w folderze <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
.
Każdy kontroler jest opisany w podrozdziale i musi mieć co najmniej te elementy:
- Nazwa zdefiniowana w polu Administrator.
- Ścieżka podłączenia określona przez pole Ścieżka.
- Tryb, UID (identyfikator użytkownika) i GID (identyfikator grupy) opisujące właściciela i tryby dostępu do plików w tej ścieżce (wszystkie opcjonalne).
- Opcjonalny atrybut. Ustaw go na true, aby system ignorował błąd zamontowania spowodowany przez kontroler cgroup, którego jądro nie obsługuje.
Przykładowy plik cgroups.json
Przykład poniżej zawiera opisy kontrolerów cgroup v1 (Cgroups
) i cgroup v2 (Cgroups2
) wraz z ich ś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 (opisująca kontrolery cgroup v1) i Cgroups2 (opisująca kontrolery cgroup v2). Wszystkie kontrolery w hierarchii grup konfiguracji v2 są zamontowane w tej samej lokalizacji.
Dlatego sekcja Cgroups2 ma własne atrybuty ścieżki, trybu, UID i GID, które opisują lokalizację i atrybuty dla elementu wyższego poziomu w hierarchii. Atrybut Ścieżka w przypadku elementu Controllers w sekcji Cgroups2 jest podany w odniesieniu do tej ścieżki głównej. W Androidzie 12 i nowszych możesz zdefiniować kontroler cgroup, który jest określony za pomocą ścieżki i trybu jako "Optional"
, ustawiając go na true
.
Plik cgroups.json
jest analizowany w ramach procesu inicjalizacji na wczesnym etapie inicjalizacji, a grupy C są montowane w określonych lokalizacjach. Aby później uzyskać lokalizacje montażu cgroup, użyj funkcji interfejsu API CgroupGetControllerPath
.
Plik profili zadań
Plik task_profiles.json
znajduje się w folderze <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
.
Używaj go do opisywania konkretnego zestawu działań, które mają być wykonywane w ramach procesu lub wątku. Z nazwą profilu powiązany jest zestaw działań, który jest używany w wywołaniach SetTaskProfiles
i SetProcessProfiles
do wywoływania działań profilu.
Przykładowy plik 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" ]
}
}
Przypisz nazwy do konkretnych plików cgroup jako wpisy na liście Atrybuty. Każdy wpis zawiera te informacje:
- Pole Nazwa określa nazwę atrybutu.
- Pole Controller (sterownik) odwołuje się do sterownika cgroup z pliku
cgroups.json
po jego nazwie. - Pole Plik zawiera nazwę konkretnego pliku w ramach tego kontrolera.
Atrybuty to odniesienia w definicjach profili zadań. Poza profilami zadań używaj ich tylko, gdy platforma wymaga bezpośredniego dostępu do tych plików, a dostępu nie można uzyskać za pomocą profili zadań. W pozostałych przypadkach używaj profili zadań, które zapewniają lepsze rozdzielenie wymaganego zachowania i szczegółów jego implementacji.
Sekcja Profile zawiera definicje profili zadań z tymi elementami:
- Pole Nazwa określa nazwę profilu.
Sekcja Działania zawiera zestaw działań wykonywanych po zastosowaniu profilu. Każda czynność ma:
- Pole Nazwa określa działanie.
- Sekcja Parametr określa zestaw parametrów działania.
Obsługiwane działania znajdziesz w tabeli:
Działanie | Parametr | Opis |
---|---|---|
SetTimerSlack |
Slack |
Czas opóźnienia w ms |
SetAttribute |
Name |
nazwa odwołująca się do atrybutu z sekcji Atrybuty. |
Value |
Wartość do zapisania w pliku reprezentowanym przez atrybuty o nazwie | |
WriteFile | FilePath | ścieżka do pliku |
Value | wartość do zapisania w pliku. | |
JoinCgroup |
Controller |
Nazwa kontrolera cgroup z cgroups.json |
Path |
Ścieżka podgrupy w hierarchii kontrolera cgroup |
Android 12 i nowsze wersje zawierają sekcję AggregateProfiles, która zawiera profile zbiorcze. Każdy z nich jest aliasem zestawu co najmniej 1 profilu. Definicje profili zbiorczych obejmują:
- Pole Nazwa określa nazwę profilu zbiorczego.
- W polu Profile (Profile) podana jest lista nazw profili uwzględnionych w profilu zbiorczym.
Gdy zastosujesz profil zbiorczy, wszystkie profile go zawierające zostaną automatycznie zastosowane. Profile zbiorcze mogą zawierać zarówno profile indywidualne, jak i inne profile zbiorcze, o ile nie ma rekurencji (profilu, który zawiera sam siebie).
polecenie init language w task_profiles
W Androidzie 12 i nowszych dostępna jest komenda task_profiles
w języku Androida Init, która ułatwia aktywację profilu zadania w przypadku konkretnego procesu. Zastępuje ono polecenie writepid
(wycofane w Androidzie 12), które służyło do przenoszenia procesu między grupami procesów. Polecenie task_profiles
zapewnia elastyczność w zakresie zmiany implementacji podrzędnych bez wpływu na warstwy wyższe. W przykładzie poniżej te 2 polecenia wykonują tę samą operację:
writepid /dev/cpuctl/top-app/tasks
Ta funkcja została wycofana w Androidzie 12. Służyła do zapisywania PID bieżącego zadania w pliku
/dev/cpuctl/top-app/tasks
.task_profiles MaxPerformance
Dołącza bieżący proces do grupy najlepszych aplikacji w sterowniku „cpu” (
cpuctl
), co powoduje zapisanie PID procesu w grupiedev/cpuctl/top-app/tasks
.
Aby przenosić zadania w hierarchiach cgroup w Androidzie 12 i nowszych, zawsze używaj polecenia task_profiles
. Akceptuje co najmniej 1 parametr, który reprezentuje nazwy profili określonych w pliku task_profiles.json
.
Profile zadań na poziomie interfejsu API
W Androidzie 12 i nowszych możesz poprawiać lub zastępować definicje w domyślnych plikach cgroups.json
i task_profiles.json
, zmieniając je na poziomie interfejsu API Androida lub w partycji dostawcy.
Aby zastąpić definicje na poziomie interfejsu API, na urządzeniu muszą znajdować się te pliki:
/system/etc/task_profiles/cgroups_<API level>.json
Używaj tego w przypadku grup skoncentrowanych na konkretnym poziomie interfejsu API.
/system/etc/task_profiles/task_profiles_<API level>.json
Używaj tego w przypadku profili związanych z poziomem interfejsu API.
Aby zastąpić definicje z partycji dostawcy, na urządzeniu muszą znajdować się te pliki:
/vendor/etc/cgroups.json
/vendor/etc/task_profiles.json
Jeśli atrybut lub definicja profilu w tych plikach ma taką samą nazwę jak w pliku domyślnym, definicja pliku (na poziomie interfejsu API lub na poziomie dostawcy) zastępuje poprzednią definicję. Pamiętaj też, że definicje na poziomie dostawcy zastępują definicje na poziomie interfejsu API. Jeśli nowa definicja ma nową nazwę, zestaw atrybutów lub profili zostanie zmodyfikowany o tą nową definicję.
System Android wczytuje pliki cgroup
i task_profile
w takiej kolejności:
- Domyślne pliki
cgroups.json
itask_profiles.json
. - pliki związane z poziomem interfejsu API (jeśli występują);
- pliki partycji dostawcy (jeśli występują);
Zmiany w dotychczasowym interfejsie API
Android 10 i nowsze wersje zachowują funkcje set_cpuset_policy
, set_sched_policy
i get_sched_policy
bez zmian w interfejsie API.
W Androidzie 10 te funkcje są jednak przenoszone do libprocessgroup
, który zawiera teraz wszystkie funkcje związane z cgroup.
Chociaż nagłówek cutils/sched_policy.h
nadal istnieje, aby uniknąć problemów z obecnym kodem, upewnij się, że nowy kod zawiera zamiast niego nowy nagłówek processgroup/sched_policy.h
.
W plikach makefile modułów, które korzystają z którejś z tych funkcji, należy dodać zależność od biblioteki libprocessgroup
. Jeśli moduł nie korzysta z żadnej innej funkcji libcutils
, usuń zależność od biblioteki libcutils
z makefile.
Interfejsy API profili zadań
Interfejsy API prywatne w processgroup/processgroup.h
są zdefiniowane w tabeli:
Typ | Interfejs API i definicja |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
Stosuje profile zadań określone w profiles do wątku określonego za pomocą identyfikatora wątku (tid) za pomocą parametru tid . |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
Stosuje profile zadań określone w profiles do procesu określonego za pomocą identyfikatorów użytkownika i procesu za pomocą parametrów uid i pid |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Zwraca wartość wskazującą, czy kontroler cgroup określony przez cgroup_name istnieje;
jeśli true , ustawia zmienną path na rdzeń tego cgroup |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Zwraca informację, czy atrybut profilu określony przez parametr attr_name istnieje. Jeśli tak, ustawia zmienną path na ścieżkę do pliku powiązanego z tym atrybutem profilu.true |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Zwraca informację, czy atrybut profilu określony przez attr_name istnieje. Jeśli tak, za pomocą parametru tid ustawia zmienną path na ścieżkę pliku powiązanego z tym atrybutem profilu oraz na wątek określony przez jego identyfikator wątku.true |
bool |
UsePerAppMemcg()
Zwraca informacje o tym, czy system jest skonfigurowany do korzystania z grup pamięci na podstawie aplikacji. |