Android 10 ve sonraki sürümlerde, geliştiricilerin bir işleme veya sürece uygulanacak bir dizi kısıtlamayı tanımlamak için kullanabileceği görev profillerine sahip bir kontrol grubu (cgroup) soyutlama katmanı kullanılır. Sistem daha sonra, kısıtlamaların uygulandığı bir veya daha fazla uygun cgroup'u seçmek için görev profillerinin öngörülen işlemlerini uygular. Böylece, temel cgroup özellik setinde yapılan değişiklikler daha yüksek yazılım katmanlarını etkilemez.
Cgroup'lar hakkında
Cgroup'lar, görev kümelerini (işlemler, iş parçacıkları ve bunların gelecekteki tüm alt öğelerinden oluşur) özel davranışlara sahip hiyerarşik gruplar halinde toplama ve bölme mekanizması sağlar. Android, CPU ve bellek kullanımı ile tahsisi gibi sistem kaynaklarını kontrol etmek ve hesaplamak için cgroup'ları kullanır. Linux çekirdeği cgroups v1 ve cgroups v2 desteklenir.
Android 9 ve önceki sürümler
Android 9 ve önceki sürümlerde init.rc
başlatma komut dosyası, kullanılabilir cgroup'ların, bunların bağlama noktalarının ve sürümlerinin kümesini içeriyordu. Bunlar değiştirilebilse de Android çerçevesi, komut dosyasına göre belirli bir sürüm ve alt grup hiyerarşisiyle belirli konumlarda belirli bir cgroup kümesinin bulunmasını bekliyordu. Bu durum, kullanılacak bir sonraki cgroup sürümünü seçme veya yeni özellikleri kullanmak için cgroup hiyerarşisini değiştirme olanağını sınırlıyordu.
Android 10 ve sonraki sürümler
Android 10 ve sonraki sürümlerde görev profilleriyle cgroup'lar kullanılır:
- Cgroup kurulumu. Geliştiriciler, cgroup kümelerini, bunların bağlama konumlarını ve özelliklerini tanımlamak için
cgroups.json
dosyalarında cgroup kurulumunu açıklar. Tüm cgroup'lar, başlatma işleminin erken başlatma aşamasında bağlanır. - Görev profilleri Bunlar, gerekli işlevselliği uygulama ayrıntılarından ayıran bir soyutlama sağlar. Android çerçevesi,
task_profiles.json
dosyasında açıklandığı şekilde görev profilleriniSetTaskProfiles
veSetProcessProfiles
API'lerini kullanarak bir işleme veya iş parçacığına uygular. (Bu API'ler Android 11 ve sonraki sürümlere özeldir.)
Geriye dönük uyumluluk sağlamak için eski işlevler set_cpuset_policy
, set_sched_policy
ve get_sched_policy
aynı API'yi ve işlevselliği sunar ancak uygulamaları görev profillerini kullanacak şekilde değiştirilmiştir. AOSP, yeni kullanım alanları için eski set_sched_policy
işlevi yerine yeni görev profilleri API'lerinin kullanılmasını önerir.
Cgroups açıklama dosyası
Cgroup'lar, cgroups.json
dosyasında açıklanmıştır. Bu dosya, <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
altında bulunur.
Her denetleyici bir alt bölümde açıklanır ve en az aşağıdakileri içermelidir:
- Denetleyici alanı tarafından tanımlanan ad.
- Yol alanı tarafından tanımlanan bağlama yolu.
- Bu yoldaki dosyaların sahibi ve erişim modlarını açıklayan Mode, UID (kullanıcı kimliği) ve GID (grup kimliği) (tümü isteğe bağlı).
- İsteğe bağlı bir özelliktir. Çekirdeğin bağlanmayı desteklemediği bir cgroup denetleyicisinin neden olduğu bağlama hatasının sistem tarafından yoksayılması için true olarak ayarlayın.
Örnek cgroups.json dosyası
Aşağıdaki örnekte, cgroup v1 (Cgroups
) ve cgroup v2 (Cgroups2
) denetleyicilerinin açıklamaları ve ilgili yolları gösterilmektedir.
{
"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"
}
]
}
}
Bu örnek dosya iki bölüm içerir: Cgroups (cgroup v1 denetleyicilerini açıklar) ve Cgroups2 (cgroup v2 denetleyicilerini açıklar). cgroups v2 hiyerarşisindeki tüm denetleyiciler aynı konuma monte edilir.
Bu nedenle, Cgroups2 bölümünde hiyerarşinin kökünün konumunu ve özelliklerini açıklamak için kendi Path, Mode, UID ve GID özellikleri bulunur. Cgroups2 altındaki Denetleyiciler için Yol özelliği, bu kök yola göre belirlenir. Android 12 ve sonraki sürümlerde, "Optional"
olarak yol ve mod ile belirtilen bir cgroup denetleyicisi tanımlayabilirsiniz. Bunun için true
olarak ayarlamanız gerekir.
cgroups.json
dosyası, erken başlatma aşamasında başlatma işleminin bir parçası olarak ayrıştırılır ve kontrol grupları belirtilen konumlara monte edilir. Daha sonra cgroup bağlama konumlarını almak için CgroupGetControllerPath
API işlevini kullanın.
Görev profilleri dosyası
task_profiles.json
dosyası <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
altında bulunur.
Bir işleme veya iş parçacığına uygulanacak belirli bir işlem grubunu tanımlamak için kullanılır. Bir profil adıyla ilişkilendirilmiş bir dizi işlem vardır. Bu ad, profil işlemlerini çağırmak için SetTaskProfiles
ve SetProcessProfiles
çağrılarında kullanılır.
Örnek task_profiles.json dosyası
{
"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" ]
}
}
Özellikler listenizdeki girişler olarak belirli cgroup dosyalarına adlar atayın. Her giriş şunları içerir:
- Ad alanı, özelliğin adını belirtir.
- Denetleyici alanı,
cgroups.json
dosyasındaki bir cgroup denetleyicisine adıyla referans verir. - Dosya alan adları, bu denetleyici altındaki belirli bir dosyayı ifade eder.
Özellikler, görev profili tanımlarındaki referanslardır. Görev profillerinin dışında, bu dosyaların doğrudan erişilmesi gerektiğinde ve erişim görev profilleri kullanılarak soyutlanamadığında yalnızca bunları kullanın. Diğer tüm durumlarda, görev profillerini kullanın. Bu profiller, gerekli davranış ile uygulama ayrıntıları arasında daha iyi bir ayrışma sağlar.
Profiller bölümünde, aşağıdakileri içeren görev profili tanımları bulunur:
- Ad alanı, profil adını tanımlar.
İşlemler bölümünde, profil uygulandığında gerçekleştirilen bir dizi işlem listelenir. Her işlemde aşağıdakiler bulunur:
- Ad alanı, işlemi belirtir.
- Params bölümünde, işlem için bir dizi parametre belirtilir.
Desteklenen işlemler tabloda listelenmiştir:
İşlem | Parametre | Açıklama |
---|---|---|
SetTimerSlack |
Slack |
Zamanlayıcıdaki gecikme (ns) |
SetAttribute |
Name |
Özellikler bölümündeki bir özelliğe referans veren ad |
Value |
Adlandırılmış özellik tarafından temsil edilen dosyaya yazılacak bir değer | |
WriteFile | FilePath | dosyanın yolu |
Value | Dosyaya yazılacak bir değer | |
JoinCgroup |
Controller |
cgroups.json adlı cgroup denetleyicisinin adı |
Path |
cgroup denetleyicisinin hiyerarşisindeki bir alt grup yolu |
Android 12 ve sonraki sürümlerde, her biri bir veya daha fazla profilden oluşan bir grubun diğer adı olan toplu profillerin yer aldığı bir AggregateProfiles bölümü bulunur. Toplu profil tanımları şunlardan oluşur:
- Ad alanı, toplu profilin adını belirtir.
- Profiller alanında, toplu profile dahil edilen profillerin adları listelenir.
Bir toplu profil uygulandığında, içerdiği tüm profiller de otomatik olarak uygulanır. Birleştirilmiş profiller, yinelemeler (kendini içeren bir profil) olmadığı sürece hem bireysel profilleri hem de diğer birleştirilmiş profilleri içerebilir.
task_profiles init language command
Belirli bir işlem için görev profili etkinleştirmeyi kolaylaştırmak amacıyla Android 12 ve sonraki sürümlerde Android Init Language'de task_profiles
komutu kullanılabilir. Bu komut, bir işlemi cgroup'lar arasında taşımak için kullanılan writepid
komutunun (Android 12'de desteği sonlandırıldı) yerini alır. task_profiles
komutu, üst katmanları etkilemeden temel uygulamaları değiştirme esnekliği sağlar. Aşağıdaki örnekte, bu iki komut aynı işlemi gerçekleştirir:
writepid /dev/cpuctl/top-app/tasks
Android 12'de desteği sonlandırıldı. Bu, mevcut görevin PID'sini
/dev/cpuctl/top-app/tasks
dosyasına yazmak için kullanılıyordu.task_profiles MaxPerformance
Mevcut işlemi "cpu" denetleyicisi altındaki en üst uygulama grubuna birleştirir (
cpuctl
). Bu işlem, sürecin PID'sinindev/cpuctl/top-app/tasks
konumuna yazılmasıyla sonuçlanır.
Android 12 ve sonraki sürümlerdeki cgroup hiyerarşilerinde görevleri taşımak için her zaman task_profiles
komutunu kullanın. task_profiles.json
dosyasında belirtilen profillerin adlarını temsil eden bir veya daha fazla parametre kabul eder.
API düzeyi başına görev profilleri
Android 12 ve sonraki sürümlerde, değişikliğinizi Android API düzeyine göre yaparak veya satıcı bölümünden yaparak varsayılan cgroups.json
ve task_profiles.json
dosyalarındaki tanımları değiştirebilir ya da geçersiz kılabilirsiniz.
Tanımları API düzeyine göre geçersiz kılmak için cihazda aşağıdaki dosyaların bulunması gerekir:
/system/etc/task_profiles/cgroups_<API level>.json
Bunu, bir API düzeyine özgü cgroup'lar için kullanın.
/system/etc/task_profiles/task_profiles_<API level>.json
Bunu, belirli bir API düzeyine özgü profiller için kullanın.
Tedarikçi bölümündeki tanımları geçersiz kılmak için cihazda aşağıdaki dosyaların bulunması gerekir:
/vendor/etc/cgroups.json
/vendor/etc/task_profiles.json
Bu dosyalardaki bir özellik veya profil tanımı, varsayılan dosyadakiyle aynı adı kullanıyorsa dosya (API düzeyi veya tedarikçi düzeyi) tanımı önceki tanımı geçersiz kılar. Ayrıca, satıcı düzeyindeki tanımların API düzeyindeki tanımları geçersiz kıldığını da unutmayın. Yeni tanımın adı farklıysa özellikler veya profiller kümesi yeni tanıma göre değiştirilir.
Android sistemi, cgroup
ve task_profile
dosyalarını şu sırayla yükler:
- Varsayılan
cgroups.json
vetask_profiles.json
dosyaları. - Varsa API düzeyine özgü dosyalar.
- Varsa satıcı bölümü dosyaları.
Mevcut API'de yapılan değişiklikler
Android 10 ve sonraki sürümlerde set_cpuset_policy
, set_sched_policy
ve get_sched_policy
işlevleri API'de değişiklik yapılmadan korunur.
Ancak Android 10, bu işlevleri libprocessgroup
içine taşır. Bu dizin artık cgroup ile ilgili tüm işlevleri içerir.
cutils/sched_policy.h
üstbilgisi hâlâ mevcut olsa da mevcut kodun bozulmasını önlemek için yeni kodun bunun yerine yeni bir processgroup/sched_policy.h
üstbilgisi içermesini sağlayın.
Bu işlevlerden herhangi birini kullanan modüller, makefile'larına libprocessgroup
kitaplığına bağımlılık eklemelidir. Bir modül başka bir libcutils
işlev kullanmıyorsa libcutils
kitaplık bağımlılığını makefile'dan kaldırın.
Görev profilleri API'leri
processgroup/processgroup.h
içindeki özel API'ler tabloda tanımlanmıştır:
Tür | API ve tanım |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
profiles içinde belirtilen görev profillerini, tid parametresini kullanarak bir iş parçacığı kimliği (tid) ile belirtilen iş parçacığına uygular. |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
uid ve pid parametrelerini kullanarak profiles içinde belirtilen görev profillerini, kullanıcı ve işlem kimlikleriyle belirtilen işleme uygular. |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
cgroup_name tarafından belirtilen bir cgroup denetleyicisinin mevcut olup olmadığını döndürür;
true ise path değişkenini söz konusu cgroup'un köküne ayarlar. |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
attr_name tarafından belirtilen bir profil özelliğinin mevcut olup olmadığını döndürür; true ise path değişkenini bu profil özelliğiyle ilişkili dosyanın yoluna ayarlar. |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
attr_name tarafından belirtilen bir profil özelliğinin mevcut olup olmadığını döndürür; true ise path değişkenini bu profil özelliğiyle ilişkili dosyanın yoluna ve tid parametresi kullanılarak iş parçacığı kimliğiyle belirtilen iş parçacığına ayarlar. |
bool |
UsePerAppMemcg()
Sistemin, uygulama başına bellek cgroup'ları kullanacak şekilde yapılandırılıp yapılandırılmadığını döndürür. |