Уровень абстракции Cgroup

Android 10 и выше используют уровень абстракции контрольной группы (cgroup) с профилями задач, которые разработчики могут использовать для описания набора (или наборов) ограничений, применяемых к потоку или процессу. Затем система следует предписанным действиям профилей задач, чтобы выбрать одну или несколько подходящих контрольных групп, через которые применяются ограничения, и изменения в базовом наборе функций контрольных групп могут быть внесены, не затрагивая более высокие уровни программного обеспечения.

О cgroups

Cgroups предоставляют механизм для агрегирования и разделения наборов задач (которые состоят из процессов, потоков и всех их будущих потомков) на иерархические группы со специализированным поведением. Android виды использования в контрольные группы контроля и учета для системных ресурсов , таких как процессор и использование памяти и распределения, с поддержкой Linux ядра контрольные группы v1 и контрольные группы v2 .

Android 9 и ниже

В Android 9 и ниже, init.rc сценарий инициализации содержал набор доступных контрольных групп, их точек крепления и версии. Хотя их можно было изменить, платформа Android ожидала, что определенный набор контрольных групп будет существовать в определенных местах с определенной версией и иерархией подгрупп на основе сценария. Это ограничивало возможность выбора следующей версии контрольной группы для использования или изменения иерархии контрольной группы для использования новых функций.

Android 10 и выше

Android 10 и выше используют контрольные группы с профилями задач:

  • Настройка контрольной группы - разработчики описывают установку контрольных групп в их cgroups.json файла определить наборы контрольных групп, а также их места установки и атрибуты. Все контрольные группы монтируются на ранней стадии инициализации.
  • Профили задач - они обеспечивают абстракцию, отделяющую требуемую функциональность от деталей ее реализации. Android структура применяет профили задач , как описано в task_profiles.json файл с процессом или потоком с использованием SetTaskProfiles и SetProcessProfiles API. (Эти API-интерфейсы уникальны для Android 11 и выше.)

Для обеспечения обратной совместимости унаследованных функций set_cpuset_policy , set_sched_policy и get_sched_policy обеспечивает тот же интерфейс и функциональность, но их реализация была изменена , чтобы использовать профили задач. Для новых случаев применения AOSP рекомендует использовать новые профили задач API , вместо унаследованной set_sched_policy функции.

Файл описания cgroups

Контрольные группы описаны в cgroups.json файл , расположенный под <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ . Каждый контроллер описан в подразделе и должен иметь как минимум следующее:

  • Имя, определяется полем контроллера.
  • Монтажный путь, заданный полем Path.
  • Режим, UID (идентификатор пользователя) и GID (идентификатор группы) , описывающий режимы владельца и доступа к файлам в рамках этого пути (все по желанию).
  • Необязательный атрибут, значение ИСТИНА , чтобы позволить системе игнорировать ошибку крепления , вызванное контроллером контрольной группы , что ядро не поддерживает монтируется.

Пример файла cgroups.json

Приведенный ниже пример описания шоу для контрольной группы (v1 Cgroups ) и контрольная группа v2 ( Cgroups2 ) контроллеров с их соответствующими путями.

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

В этом примере файл содержит два раздела, контрольных группы (описание контроллеров v1 контрольной группы) и Cgroups2 (описание контроллеров v2 контрольной группы). Все контроллеры в иерархии cgroups v2 монтируются в одном месте. Таким образом, секция Cgroups2 имеет свой собственный путь, режим, UID и GID атрибуты для описания местоположения и атрибутов для корня иерархии. Атрибут Path для контроллеров под Cgroups2 относителен к этому корневому пути. В Android 12 и выше , вы можете определить контроллер контрольной группы, задаваемый с путем и режимом как "Optional" , установив его true .

cgroups.json файл обрабатывается как часть процесса инициализации, во время ранней стадии инициализации, а контрольные группы установлены в указанных местах. Для того, чтобы позже получить контрольную группу монтажа мест, используйте CgroupGetControllerPath функцию API.

Файл профилей задач

task_profiles.json файл находится под <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ . Используйте его для описания определенного набора действий, которые будут применяться к процессу или потоку. Набор действий связано с именем профиля, который используется в SetTaskProfiles и SetProcessProfiles вызовов для вызова действия профиля.

Пример файла 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" ]
     }
}

Присваивать имена конкретных файлов в качестве контрольной группы записей в списке атрибутов. Каждая запись содержит следующее:

  • Имя поля - определяет имя атрибута.
  • Поле Controller - ссылки контрольной группы контроллер из cgroups.json файла по его имени.
  • Поле Файл - называет конкретный файл под этим контроллером.

Атрибуты ссылки в определениях профильных задач. Вне профилей задач, использовать их только тогда , когда структура требует прямого доступа к этим файлам, а также доступ не может абстрагироваться с помощью профилей задач. Во всех остальных случаях используйте профили задач; они обеспечивают лучшую развязку между требуемым поведением и деталями его реализации.

В разделе Профили содержит определение профиля задачи со следующим:

  • Имя поля - определяет имя профиля.
  • Действия раздел - перечисляет набор действий , выполняемых при применении профиля. Каждое действие имеет следующее:

    • Имя поля с указанием действий
    • Раздел Params задания набора параметров для действия

Поддерживаемые действия перечислены в таблице ниже.

Действие Параметр Описание
SetTimerSlack Slack Задержка таймера в нс
SetAttribute Name Имя ссылки атрибут из раздела Атрибуты
Value Значение, которое будет записано в файл, представленный указанным атрибутом
WriteFile FilePath путь к файлу
Value значение, которое будет записано в файл
JoinCgroup Controller Имя контроллера контрольной группы из cgroups.json
Path Путь к подгруппе в иерархии контроллера cgroup

Android - 12 и выше особенность секция AggregateProfiles , которая содержит агрегатные профили, каждый из которых является псевдонимом для набора из одного или нескольких профилей. Определения совокупного профиля состоят из следующего:

  • Имя поля - определяет имя совокупного профиля.
  • Профили поле - перечислены имена профилей , включенных в совокупный профиль.

Когда применяется совокупный профиль, все содержащиеся в нем профили также применяются автоматически. Агрегированные профили могут содержать как отдельные профили, так и другие агрегированные профили, если нет рекурсий (профиль, включающий самого себя).

task_profiles команда языка инициализации

task_profiles команда в Android Init Язык доступен для Android 12 и выше , чтобы облегчить задачу активации профиля для процесса конкретного. Он заменяет writepid команды (устаревшее в Android 12) , который был использован для переноса процесса между контрольными группами. task_profiles команда обеспечивает гибкость для изменения , лежащие в основе реализаций без влияния на верхние слои. В приведенном ниже примере эти две команды эффективно выполняют одну и ту же операцию:

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

    Запрещено в Android 12 - Была использовано для записи PID текущей задачи в /dev/cpuctl/top-app/tasks файл.

  • task_profiles MaxPerformance

    Присоединяется текущий процесс в группе топ-приложение под «CPU» контроллера ( cpuctl ), что приводит к записи PID процесса к dev/cpuctl/top-app/tasks .

Всегда используйте task_profiles команду для переноса задач в контрольной группе иерархий в Android 12 и выше. Он принимает один или несколько параметров, представляющие имена профилей , указанных в task_profiles.json файл.

Профили задач на уровне API

В Android 12 и выше, вы можете изменить или определения переопределения по умолчанию cgroups.json и task_profiles.json файлов, либо основывая свое изменение на уровне Android API, или сделать его из раздела поставщика.

Чтобы переопределить определения на основе уровня API, на устройстве должны присутствовать следующие файлы:

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

    Используйте это для групп, специфичных для уровня API.

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

    Используйте это для профилей, относящихся к уровню API.

Чтобы переопределить определения из раздела поставщика, на устройстве должны присутствовать следующие файлы:

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

Если атрибут или определение профиля в этих файлах использует то же имя, что и в файле по умолчанию, определение файла (на уровне API или на уровне поставщика) переопределяет предыдущее определение. Также обратите внимание, что определения на уровне поставщика имеют приоритет над определениями на уровне API. Если новое определение имеет новое имя, то в набор атрибутов или профилей вносится новое определение.

Система загружает Android в cgroup и task_profile файлы в следующем порядке:

  1. По умолчанию cgroups.json и task_profiles.json файлов.
  2. Файлы, специфичные для уровня API, если они есть.
  3. Файлы разделов поставщика, если они есть.

Изменения в существующем API

Android 10 и выше поддерживает функцию set_cpuset_policy , set_sched_policy и get_sched_policy без изменений в API. Тем не менее, Android 10 перемещает эти функции в libprocessgroup , который теперь содержит все контрольной группы , связанные с функциональностью.

Хотя cutils/sched_policy.h заголовок все еще существует, чтобы избежать нарушения существующего кода обеспечения того , чтобы новый код включает в себя новый processgroup/sched_policy.h заголовок вместо этого.

Модули , которые используют любой из этих функций следует добавить зависимость от libprocessgroup библиотеки в их Makefile. Если модуль не использует никаких других libcutils функциональность, падение libcutils библиотеки зависимости от Makefile.

API профилей задач

Частные APIs в processgroup/processgroup.h определены в таблице ниже:

Тип API и определение
bool SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles)

Применяется профили задач , указанных в profiles с резьбой , указанной с помощью резьбы ID (TID) , используя свой tid параметр.

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

Применяются профили задач , указанных в profiles для процесса , указанного его идентификаторами пользователей и процессов с использованием uid и pid параметров

bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)

Возвращает ли контроллер контрольной группы определяется cgroup_name существует; если true , устанавливает path переменную в корне этого контрольной группы

bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)

Возвращает указанный ли атрибут профиля по attr_name существует; если true , устанавливает path переменного в пути файла , связанный с этим атрибутом профиля.

bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)

Возвращает указанный ли атрибут профиля по attr_name существует; если true , устанавливает path переменной в путь файла , связанного с этим атрибутом профиля, и нити , указанной ее нити ID с помощью tid параметра.

bool UsePerAppMemcg()

Возвращает, настроена ли система на использование контрольных групп памяти для каждого приложения.