Capa de abstracción de cgroup

Android 10 y las versiones posteriores usan un grupo de control (cgroup) capa de abstracción con perfiles de tareas, que los desarrolladores pueden usar para describir un conjunto (o conjuntos) de restricciones para aplicar a un subproceso o proceso. Luego, el sistema sigue las acciones prescritas de los perfiles de tareas para seleccionar una o más a los cgroups adecuados, a través de los cuales se aplican restricciones, y los cambios El conjunto de atributos de cgroup subyacente puede crearse sin afectar el software de mayor nivel capas.

Información acerca de cgroups

Los cgroups proporcionan un mecanismo para agregar y particionar conjuntos de tareas (que consisten en procesos, subprocesos y todos sus elementos secundarios futuros) en grupos jerárquicos con un comportamiento especializado. Android usa cgroups para controlar y responder los recursos del sistema, como el uso y la asignación de memoria y CPU, con compatibilidad Kernel de Linux cgroups v1 y cgroups v2.

Android 9 y versiones anteriores

En Android 9 y versiones anteriores, la secuencia de comandos de inicialización init.rc contenía el conjunto de los cgroups disponibles, sus puntos de activación y sus versiones. Si bien estos podrían ser el framework de Android esperaba que existiera un conjunto específico de cgroups ubicaciones específicas con una jerarquía de versión y subgrupos específica, según el secuencia de comandos. Esto limitaba la capacidad de elegir la siguiente versión de cgroup que usar. cambiar la jerarquía de cgroup para usar nuevos atributos.

Android 10 y versiones posteriores

Android 10 y versiones posteriores usan cgroup con perfiles de tareas:

  • Configuración de cgroup. Los desarrolladores describen la configuración de cgroups en su cgroups.json para definir conjuntos de cgroups, y sus atributos y ubicaciones de activación. Todos los cgroups se activan durante la etapa first-init de la inicialización el proceso de administración de recursos.
  • Perfiles de tareas. Estos proporcionan una abstracción que separa los elementos desde los detalles de su implementación. El framework de Android aplica los perfiles de tareas como se describe en el archivo task_profiles.json a un proceso o subproceso con las APIs de SetTaskProfiles y SetProcessProfiles. (Estas APIs son exclusivas de Android 11 y versiones posteriores).

Para ofrecer retrocompatibilidad, las funciones heredadas set_cpuset_policy, set_sched_policy y get_sched_policy proporcionan la misma API y funcionalidad, pero su implementación se modificó para usar perfiles de tareas. Para uso nuevo casos, AOSP recomienda usar nuevas APIs de perfiles de tareas en lugar de las heredadas función set_sched_policy.

Archivo de descripción de cgroups

Los cgroups se describen en el cgroups.json ubicado en <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Cada controlador se describe en una subsección y debe tener un mínimo de lo siguiente:

  • Nombre, definido por el campo Controller.
  • Ruta de activación, definida por el campo Path.
  • Modo, UID (ID de usuario) y GID (ID de grupo) que describen el propietario y los modos de acceso de los archivos de esta ruta de acceso (todos opcionales).
  • Atributo opcional, establecido en true para permitir que el sistema ignore el montaje error causado por un controlador de cgroup que no admite la activación del kernel.

Ejemplo de archivo cgroups.json

En el siguiente ejemplo, se muestran descripciones de cgroup v1 (Cgroups) y cgroup v2 (Cgroups2) con sus respectivas rutas de acceso.

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

Este archivo de ejemplo contiene dos secciones, Cgroups (en las que se describe cgroup v1 controladores) y Cgroups2 (que describen los controladores de cgroup v2). Todas de la jerarquía de cgroups v2 se activan en la misma ubicación. Por lo tanto, la sección Cgroups2 tiene su propia Ruta de acceso, Modo, UID y atributos de GID para describir la ubicación y los atributos de la raíz de la en la nube. El atributo Path para Controllers en Cgroups2 es en relación con esa ruta raíz. En Android 12 y versiones posteriores, puedes definir un cgroup controlador que se especifica con la ruta de acceso y el modo como "Optional" configúralo en true.

El archivo cgroups.json se analiza como parte del proceso de init, durante la etapa de inicio anticipado, y los cgroups se activan en las ubicaciones especificadas. Para obtener más adelante las ubicaciones de activación de cgroup, usa la función de la API de CgroupGetControllerPath.

Archivo de perfiles de tareas

El task_profiles.json se encuentra en <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Úsalo para describir un conjunto específico de acciones que se aplicarán a un proceso o a un conversación. Un conjunto de acciones se asocia a un nombre de perfil, que se usa en Llamadas SetTaskProfiles y SetProcessProfiles para invocar acciones de perfil

Ejemplo de archivo 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" ]
     }
}

Asigna nombres a archivos cgroup específicos como entradas en la lista Atributos. Cada entrada contiene lo siguiente:

  • El campo Name especifica el nombre del atributo.
  • El campo Controller hace referencia a un controlador de cgroup del archivo cgroups.json por su nombre.
  • El campo File nombra un archivo específico en este controlador.

Los atributos son referencias en las definiciones de perfiles de tareas. Fuera de la tarea Úsalos solo cuando el framework requiera acceso directo a esos archivos, y el acceso no se puede abstraer usando perfiles de tareas. En todos los demás casos, usar perfiles de tareas; proporcionan una mejor separación entre el comportamiento requerido y los detalles de su implementación.

La sección Profiles contiene definiciones de perfiles de tareas con lo siguiente:

  • Name define el nombre del perfil.
  • Actions, que muestra un conjunto de acciones realizadas cuando el perfil se se aplicó. Cada acción tiene lo siguiente:

    • Name especifica la acción.
    • La sección Params especifica un conjunto de parámetros para la acción.

Las acciones admitidas se enumeran en la tabla:

Acción Parámetro Descripción
SetTimerSlack Slack Tiempo de inactividad del temporizador en ns
SetAttribute Name Un nombre que hace referencia a un atributo de la sección Atributos
Value Un valor que se escribirá en el archivo representado por el atributo nombrado
WriteFileFilePathruta de acceso al archivo
Valueun valor que se escribirá en el archivo
JoinCgroup Controller Un nombre del controlador de cgroup de cgroups.json
Path Es una ruta de subgrupo en la jerarquía del controlador de cgroup.

Android 12 y las versiones posteriores tienen un AggregateProfile. que contiene perfiles agregados, cada uno de los cuales es un alias para un conjunto de uno o más perfiles. Las definiciones de perfiles agregados constan de lo siguiente:

  • El campo Name especifica el nombre del perfil agregado.
  • Profiles muestra los nombres de los perfiles incluidos en la perfil agregado.

Cuando se aplica un perfil agregado, también se aplican automáticamente todos los perfiles que lo contienen. Los perfiles agregados pueden contener tanto perfiles individuales u otros perfiles agregados, siempre y cuando no haya recursiones (un perfil que se incluya a sí misma).

Comando de lenguaje init de task_profiles

Un comando task_profiles en Android Init Language está disponible para Android 12 y versiones posteriores para facilitar la activación del perfil de tareas para un proceso específico. Reemplaza el comando writepid (obsoleto en Android 12) que se usaba para migrar un proceso entre cgroups. El comando task_profiles proporciona flexibilidad para lo siguiente: cambiando las implementaciones subyacentes sin que esto afecte las capas superiores. En la ejemplo a continuación, estos dos comandos realizan efectivamente la misma operación:

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

    dejó de estar disponible en Android 12; se usó para escribir el PID de la tarea actual en el archivo /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    Une el proceso actual al grupo de apps principales en el controlador "cpu" (cpuctl), lo que genera la escritura del PID del proceso en dev/cpuctl/top-app/tasks.

Usa siempre el comando task_profiles para migrar tareas en jerarquías de cgroup en Android 12 y versiones posteriores Acepta uno o más parámetros que representan los nombres de los perfiles especificados en el archivo task_profiles.json.

Perfiles de tareas por nivel de API

En Android 12 y versiones posteriores, puedes enmendar o anular en los archivos cgroups.json y task_profiles.json predeterminados, basar tu cambio en el nivel de API de Android o hacerlo en el proveedor por cada partición.

Para anular las definiciones según el nivel de API, los siguientes archivos deben estar presentes en el dispositivo:

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

    Úsalo para cgroups específicos de un nivel de API.

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

    Úsalo para perfiles específicos de un nivel de API.

Para anular las definiciones de la partición del proveedor, los siguientes archivos deben estar presente en el dispositivo:

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

Si un atributo o una definición de perfil de estos archivos usa el mismo nombre que está en el archivo predeterminado, la definición del archivo (nivel de API o proveedor) anula la definición anterior. Ten en cuenta también que las definiciones a nivel del proveedor anulan Definiciones de nivel de API Si la nueva definición tiene un nuevo nombre, entonces el conjunto de atributos o perfiles se enmienda con la nueva definición.

El sistema Android carga los archivos cgroup y task_profile en este orden:

  1. Predeterminado cgroups.json y task_profiles.json archivos.
  2. Archivos específicos del nivel de API, si están presentes
  3. Archivos de partición del proveedor, si están presentes.

Cambios en la API existente

Android 10 y las versiones posteriores conservan las funciones set_cpuset_policy, set_sched_policy y get_sched_policy sin cambios en la API. Sin embargo, Android 10 traslada estas funciones a libprocessgroup, que ahora contiene todas las funcionalidades relacionadas con cgroup.

Aunque el encabezado cutils/sched_policy.h todavía existe, para evitar romper el código existente garantizan que el código nuevo incluya un nuevo processgroup/sched_policy.h encabezado.

Los módulos que usan cualquiera de estas funciones deben agregar la dependencia del libprocessgroup en su archivo makefile. Si un módulo no usa ningún otro Funcionalidad libcutils, descarta libcutils. la dependencia de biblioteca del archivo makefile.

APIs de perfiles de tareas

Las APIs privadas en processgroup/processgroup.h se definen en la tabla:

Tipo API y definición
bool SetTaskProfiles(int tid, const std::vector& profiles)
Aplica los perfiles de tareas especificados en profiles al subproceso que especificó. un ID de subproceso (tid) mediante su parámetro tid.
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles)
Aplica los perfiles de tareas especificados en profiles al proceso que especifican los IDs de usuario y proceso con los parámetros uid y pid.
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Devuelve si existe un controlador de cgroup especificado por cgroup_name. Si es true, establece la variable path en la raíz de ese cgroup.
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Muestra si existe un atributo de perfil especificado por attr_name. si true, establece la variable path en la ruta de acceso del archivo asociado con ese atributo de perfil.
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Muestra si existe un atributo de perfil especificado por attr_name. si true, establece la variable path en la ruta de acceso del archivo asociado con ese atributo de perfil y al subproceso especificado por su ID de subproceso mediante el parámetro tid.
bool UsePerAppMemcg()
Muestra si el sistema está configurado para usar cgroups de memoria por app.