Grup Soyutlama Katmanı

Android 10 ve üzeri, geliştiricilerin bir iş parçacığına veya işleme uygulanacak kısıtlama kümesini (veya kümelerini) tanımlamak için kullanabileceği görev profillerine sahip bir kontrol grubu (cgroup) soyutlama katmanı kullanır. Sistem daha sonra, kısıtlamaların uygulandığı bir veya daha fazla uygun grup seçmek için görev profillerinin önceden belirlenmiş eylemlerini takip eder ve temel grup özellik setinde daha yüksek yazılım katmanlarını etkilemeden değişiklikler yapılabilir.

Gruplar hakkında

Cgroup'lar, görev kümelerini (süreçlerden, iş parçacıklarından ve bunların gelecekteki tüm alt öğelerinden oluşan) uzmanlaşmış davranışlara sahip hiyerarşik gruplar halinde toplamak ve bölümlemek için bir mekanizma sağlar. Android, Linux çekirdeği cgroups v1 ve cgroups v2 desteğiyle CPU ve bellek kullanımı ve tahsisi gibi sistem kaynaklarını kontrol etmek ve hesaba katmak için cgroups'u kullanır.

Android 9 ve altı

Android 9 ve önceki sürümlerde, init.rc başlatma komut dosyası, mevcut grup kümelerini, bunların montaj noktalarını ve sürümlerini içeriyordu. Bunlar değiştirilebilir olsa da, Android çerçevesi, komut dosyasına dayalı olarak belirli bir sürüm ve alt grup hiyerarşisine sahip belirli konumlarda belirli bir grup kümesinin var olmasını bekliyordu. Bu, kullanılacak bir sonraki grup sürümünü seçme veya yeni özellikleri kullanacak şekilde grup hiyerarşisini değiştirme yeteneğini sınırladı.

Android 10 ve üzeri

Android 10 ve üzeri, görev profillerine sahip gruplar kullanır:

  • Cgroup kurulumu - geliştiriciler, cgroups setlerini ve bunların montaj konumlarını ve niteliklerini tanımlamak için cgroups.json dosyasında cgroups kurulumunu açıklar. Tüm gruplar, başlatma sürecinin erken başlangıç ​​aşamasında bağlanır.
  • Görev profilleri - bunlar gerekli işlevselliği uygulamanın ayrıntılarından ayıran bir soyutlama sağlar. Android çerçevesi, görev profillerini, task_profiles.json dosyasında açıklandığı şekilde SetTaskProfiles ve SetProcessProfiles 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 sağlar, ancak uygulamaları görev profillerini kullanacak şekilde değiştirildi. Yeni kullanım durumları için AOSP, eski set_sched_policy işlevi yerine yeni görev profilleri API'lerinin kullanılmasını önerir.

Cgroups açıklama dosyası

Cgroup'lar <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ altında bulunan cgroups.json dosyasında açıklanmaktadır. Her denetleyici bir alt bölümde açıklanmıştır ve en az aşağıdaki özelliklere sahip olmalıdır:

  • Denetleyici alanı tarafından tanımlanan ad.
  • Yol alanı tarafından tanımlanan montaj yolu.
  • Mode , UID (kullanıcı kimliği) ve GID (grup kimliği), bu yol altındaki dosyaların sahibini ve erişim modlarını açıklar (tümü isteğe bağlıdır).
  • Çekirdeğin bağlanmayı desteklemediği bir cgroup denetleyicisinin neden olduğu montaj hatasını sistemin yok saymasına izin vermek için true olarak ayarlanan isteğe bağlı öznitelik.

Örnek cgroups.json dosyası

Aşağıdaki örnek, cgroup v1 ( Cgroups ) ve cgroup v2 ( Cgroups2 ) denetleyicilerine ilişkin açıklamaları ilgili yollarıyla birlikte gösterir.

{
  "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). Grupların v2 hiyerarşisindeki tüm denetleyiciler aynı konuma monte edilir. Bu nedenle, Cgroups2 bölümünün hiyerarşinin kökünün konumunu ve niteliklerini tanımlamak için kendi Path , Mode , UID ve GID nitelikleri vardır. Cgroups2 altındaki Denetleyiciler için Yol özelliği bu kök yola göredir. Android 12 ve üzeri sürümlerde, yol ve modla belirtilen bir grup denetleyicisini "Optional" olarak ayarlayarak true olarak tanımlayabilirsiniz.

cgroups.json dosyası, başlangıç ​​sürecinin bir parçası olarak erken başlatma aşamasında ayrıştırılır ve cgroup'lar belirtilen konumlara bağlanır. Daha sonra grup montaj konumlarını edinmek 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 dizi eylemi tanımlamak için kullanın. Bir dizi eylem, profil eylemlerini çağırmak için SetTaskProfiles ve SetProcessProfiles çağrılarında kullanılan bir profil adıyla ilişkilendirilir.

Örnek görev_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" ]
     }
}

Nitelikler listenizdeki girişler olarak belirli grup dosyalarına adlar atayın. Her giriş aşağıdakileri içerir:

  • Ad alanı - Niteliğin adını belirtir.
  • Denetleyici alanı - cgroups.json dosyasındaki bir cgroup denetleyicisine adıyla başvurur.
  • Dosya alanı - bu denetleyicinin altındaki belirli bir dosyayı adlandırır.

Nitelikler , görev profili tanımlarındaki referanslardır. Görev profilleri dışında, bunları yalnızca çerçeve bu dosyalara doğrudan erişim gerektirdiğinde ve erişim, görev profilleri kullanılarak soyutlanamadığında kullanın. Diğer tüm durumlarda görev profillerini kullanın; gerekli davranış ile uygulama ayrıntıları arasında daha iyi bir ayrım sağlarlar.

Profiller bölümü aşağıdakileri içeren görev profili tanımlarını içerir:

  • Ad alanı - profil adını tanımlar.
  • Eylemler bölümü - profil uygulandığında gerçekleştirilen bir dizi eylemi listeler. Her eylemde aşağıdakiler bulunur:

    • Eylemi belirten ad alanı
    • Eylem için bir dizi parametreyi belirten Params bölümü

Desteklenen eylemler aşağıdaki tabloda listelenmiştir.

Aksiyon Parametre Tanım
SetTimerSlack Slack Ns'de zamanlayıcı gevşekliği
SetAttribute Name Nitelikler bölümündeki bir niteliğe başvuran ad
Value Adlandırılmış öznitelik 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 grup denetleyicisinin adı
Path Grup denetleyicisinin hiyerarşisindeki bir alt grup yolu

Android 12 ve sonraki sürümlerde, her biri bir veya daha fazla profil kümesinin takma adı olan toplu profiller içeren bir AggregateProfiles bölümü bulunur. Toplu profil tanımları aşağıdakilerden oluşur:

  • Ad alanı - toplu profilin adını belirtir.
  • Profiller alanı - toplu profile dahil edilen profillerin adlarını listeler.

Birleştirilmiş profil uygulandığında, tüm içeren profiller de otomatik olarak uygulanır. Toplu profiller, özyineleme (kendisini içeren bir profil) olmadığı sürece hem bireysel profilleri hem de diğer toplu profilleri içerebilir.

görev_profilleri başlangıç ​​dili komutu

Belirli bir işlem için görev profili etkinleştirmesini kolaylaştırmak amacıyla Android 12 ve sonraki sürümlerde Android Init Dilinde bir task_profiles komutu mevcuttur. Bir işlemi gruplar arasında taşımak için kullanılan writepid komutunun (Android 12'de kullanımdan kaldırılmıştır) yerini alır. task_profiles komutu, üst katmanları etkilemeden temeldeki uygulamaları değiştirmek için esneklik sağlar. Aşağıdaki örnekte bu iki komut aynı işlemi etkili bir şekilde gerçekleştirir:

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

    Android 12'de kullanımdan kaldırıldı - Geçerli görevin PID'sini /dev/cpuctl/top-app/tasks dosyasına yazmak için kullanıldı.

  • task_profiles MaxPerformance

    Geçerli işlemi "cpu" denetleyicisi ( cpuctl ) altındaki üst uygulama grubuna birleştirir; bu, işlemin PID'sinin dev/cpuctl/top-app/tasks yazılmasıyla sonuçlanır.

Android 12 ve sonraki sürümlerde grup hiyerarşilerindeki 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 parametreyi kabul eder.

API düzeyinde görev profilleri başına

Android 12 ve sonraki sürümlerde, varsayılan cgroups.json ve task_profiles.json dosyalarındaki tanımları, değişikliğinizi Android API düzeyine dayalı olarak veya satıcı bölümünden yaparak değiştirebilir veya 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:

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

    Bunu bir API düzeyine özgü gruplar için kullanın.

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

    Bunu bir API düzeyine özgü profiller için kullanın.

Satıcı 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 öznitelik veya profil tanımı, varsayılan dosyadakiyle aynı adı kullanıyorsa, dosya (API düzeyi veya satıcı 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ı unutmayın. Yeni tanımın yeni bir adı varsa, nitelikler veya profiller kümesi yeni tanımla değiştirilir.

Android sistemi cgroup ve task_profile dosyalarını şu sırayla yükler:

  1. Varsayılan cgroups.json ve task_profiles.json dosyaları.
  2. Varsa, API düzeyine özgü dosyalar.
  3. Varsa satıcı bölüm dosyaları.

Mevcut API'de yapılan değişiklikler

Android 10 ve üzeri, set_cpuset_policy , set_sched_policy ve get_sched_policy işlevlerini API'de değişiklik yapmadan korur. Ancak Android 10, bu işlevleri artık cgroup ile ilgili tüm işlevleri içeren libprocessgroup taşıyor.

cutils/sched_policy.h başlığı hala mevcut olsa da, mevcut kodun bozulmasını önlemek için yeni kodun bunun yerine yeni bir processgroup/sched_policy.h başlığı içerdiğinden emin olun.

Bu işlevlerden herhangi birini kullanan modüller, makefile dosyasına libprocessgroup kitaplığına bağımlılık eklemelidir. Bir modül başka herhangi bir libcutils işlevini kullanmıyorsa, libcutils kitaplığı bağımlılığını makefile'dan bırakın.

Görev profilleri API'leri

processgroup/processgroup.h özel API'ler aşağıdaki tabloda tanımlanmıştır:

Tip API ve Tanım
bool SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles)

profiles belirtilen görev profillerini, tid parametresini kullanarak bir iş parçacığı kimliği (tid) tarafından belirtilen iş parçacığına uygular.

bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles)

profiles belirtilen görev profillerini, kullanıcı kimliği ve işlem kimlikleri tarafından belirtilen işleme, uid ve pid parametrelerini kullanarak 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; eğer true , path değişkenini o grubun 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 söz konusu profil niteliğ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 özniteliğiyle ilişkili dosyanın yoluna ve tid parametresini kullanarak iş parçacığı kimliğiyle belirtilen iş parçacığına ayarlar.

bool UsePerAppMemcg()

Sistemin uygulama başına bellek gruplarını kullanacak şekilde yapılandırılıp yapılandırılmadığını döndürür.