Android 10 y versiones posteriores utilizan una capa de abstracción de grupo de control (cgroup) con perfiles de tareas, que los desarrolladores pueden usar para describir un conjunto (o conjuntos) de restricciones para aplicar a un hilo o proceso. Luego, el sistema sigue las acciones prescritas de los perfiles de tareas para seleccionar uno o más cgroups apropiados, a través de los cuales se aplican restricciones y se pueden realizar cambios en el conjunto de características subyacentes del cgroup sin afectar las capas superiores de software.
Acerca de los grupos c
Los Cgroups proporcionan un mecanismo para agregar y dividir conjuntos de tareas (que constan de procesos, subprocesos y todos sus futuros hijos) en grupos jerárquicos con comportamiento especializado. Android usa cgroups para controlar y contabilizar los recursos del sistema, como el uso y la asignación de CPU y memoria, con soporte para cgroups v1 y cgroups v2 del kernel de Linux.
Android 9 y anteriores
En Android 9 y versiones anteriores, el script de inicialización init.rc
contenía el conjunto de cgroups disponibles, sus puntos de montaje y versiones. Si bien estos podrían cambiarse, el marco de trabajo de Android esperaba que existiera un conjunto específico de cgroups en ubicaciones específicas con una versión específica y una jerarquía de subgrupos, según el script. Esto limitó la capacidad de elegir la siguiente versión de cgroup a usar o de cambiar la jerarquía de cgroup para usar nuevas funciones.
Android 10 y superior
Android 10 y versiones posteriores utilizan cgroups con perfiles de tareas:
- Configuración del grupo C. Los desarrolladores describen la configuración de cgroups en su archivo
cgroups.json
para definir conjuntos de cgroups y sus ubicaciones y atributos de montaje. Todos los cgroups se montan durante la etapa inicial del proceso de inicialización. - Perfiles de tareas. Estos proporcionan una abstracción que desacopla la funcionalidad requerida de los detalles de su implementación. El marco de trabajo de Android aplica los perfiles de tareas como se describe en el archivo
task_profiles.json
a un proceso o subproceso mediante las APISetTaskProfiles
ySetProcessProfiles
. (Estas API son exclusivas de Android 11 y versiones posteriores).
Para proporcionar compatibilidad con versiones anteriores, las funciones heredadas set_cpuset_policy
, set_sched_policy
y get_sched_policy
proporcionan la misma API y funcionalidad, pero su implementación se ha modificado para utilizar perfiles de tareas. Para nuevos casos de uso, AOSP recomienda utilizar nuevas API de perfiles de tareas en lugar de la función heredada set_sched_policy
.
Archivo de descripción de grupos C
Los Cgroups se describen en el archivo 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 Controlador .
- Ruta de montaje, definida por el campo Ruta .
- Modo , UID (ID de usuario) y GID (ID de grupo) que describen el propietario y los modos de acceso a los archivos en esta ruta (todos opcionales).
- Atributo opcional , establecido en verdadero para permitir que el sistema ignore el error de montaje causado por un controlador cgroup cuyo montaje el kernel no admite.
Ejemplo de archivo cgroups.json
El siguiente ejemplo muestra descripciones de los controladores cgroup v1 ( Cgroups
) y cgroup v2 ( Cgroups2
) con sus respectivas rutas.
{
"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 (que describe los controladores cgroup v1) y Cgroups2 (que describe los controladores cgroup v2). Todos los controladores de la jerarquía cgroups v2 están montados en la misma ubicación. Por lo tanto, la sección Cgroups2 tiene sus propios atributos Path , Mode , UID y GID para describir la ubicación y los atributos de la raíz de la jerarquía. El atributo Ruta para controladores en Cgroups2 es relativo a esa ruta raíz. En Android 12 y versiones posteriores, puedes definir un controlador cgroup que se especifica con la ruta y el modo como "Optional"
configurándolo en true
.
El archivo cgroups.json
se analiza como parte del proceso de inicio, durante la etapa de inicio inicial, y los cgroups se montan en las ubicaciones especificadas. Para obtener posteriormente las ubicaciones de montaje de cgroup, utilice la función API CgroupGetControllerPath
.
Archivo de perfiles de tareas
El archivo task_profiles.json
se encuentra en <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
. Úselo para describir un conjunto específico de acciones que se aplicarán a un proceso o hilo. Un conjunto de acciones está asociado con un nombre de perfil, que se utiliza en las 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" ]
}
}
Asigne nombres a archivos cgroup específicos como entradas en su lista de Atributos . Cada entrada contiene lo siguiente:
- El campo Nombre especifica el nombre del atributo.
- El campo Controlador hace referencia a un controlador cgroup del archivo
cgroups.json
, por su nombre. - El campo Archivo nombra un archivo específico bajo este controlador.
Los atributos son referencias en las definiciones de perfiles de tareas. Fuera de los perfiles de tareas, utilícelos solo cuando el marco requiera acceso directo a esos archivos y el acceso no se pueda abstraer mediante perfiles de tareas. En todos los demás casos, utilice perfiles de tareas; Proporcionan un mejor desacoplamiento entre el comportamiento requerido y sus detalles de implementación.
La sección Perfiles contiene definiciones de perfiles de tareas con lo siguiente:
- El campo Nombre define el nombre del perfil.
La sección Acciones enumera un conjunto de acciones realizadas cuando se aplica el perfil. Cada acción tiene lo siguiente:
- El campo de nombre especifica la acción.
- La sección Parámetros 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 | Temporizador flojo 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 |
WriteFile | FilePath | ruta al archivo | Value | un valor que se escribirá en el archivo |
JoinCgroup | Controller | Un nombre del controlador cgroup de cgroups.json |
Path | Una ruta de subgrupo en la jerarquía del controlador cgroup |
Android 12 y versiones posteriores cuentan con una sección AggregateProfiles 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 Nombre especifica el nombre del perfil agregado.
- El campo Perfiles enumera los nombres de los perfiles incluidos en el perfil agregado.
Cuando se aplica un perfil agregado, todos los perfiles que lo contienen también se aplican automáticamente. Los perfiles agregados pueden contener tanto perfiles individuales como otros perfiles agregados, siempre que no haya recursividades (un perfil que se incluye a sí mismo).
comando de idioma de inicio task_profiles
Un comando task_profiles
en el lenguaje de inicio de Android está disponible para Android 12 y versiones posteriores para facilitar la activación del perfil de tarea para un proceso específico. Reemplaza el comando writepid
(obsoleto en Android 12) que se usó para migrar un proceso entre cgroups. El comando task_profiles
proporciona flexibilidad para cambiar las implementaciones subyacentes sin ningún efecto en las capas superiores. En el siguiente ejemplo, estos dos comandos realizan efectivamente la misma operación:
writepid /dev/cpuctl/top-app/tasks
Obsoleto en Android 12, esto 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 aplicaciones principales bajo el controlador "cpu" (
cpuctl
), lo que da como resultado escribir el PID del proceso endev/cpuctl/top-app/tasks
.
Utilice 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
.
Por perfiles de tarea a nivel de API
En Android 12 y versiones posteriores, puede modificar o anular las definiciones en los archivos cgroups.json
y task_profiles.json
predeterminados, ya sea basando el cambio en el nivel de API de Android o haciéndolo desde la partición del proveedor.
Para anular las definiciones basadas en el nivel de API, los siguientes archivos deben estar presentes en el dispositivo:
pro/system/etc/task_profiles/cgroups_<API level>.json
Utilice esto para cgroups específicos de un nivel de API.
/system/etc/task_profiles/task_profiles_<API level>.json
Utilice esto para perfiles específicos de un nivel de API.
Para anular las definiciones de la partición del proveedor, los siguientes archivos deben estar presentes en el dispositivo:
-
/vendor/etc/cgroups.json
-
/vendor/etc/task_profiles.json
Si un atributo o una definición de perfil en estos archivos usa el mismo nombre que en el archivo predeterminado, la definición del archivo (nivel de API o nivel de proveedor) anula la definición anterior. Tenga en cuenta también que las definiciones a nivel de proveedor anulan las definiciones a nivel de API. Si la nueva definición tiene un nuevo nombre, entonces el conjunto de atributos o perfiles se modifica con la nueva definición.
El sistema Android carga los archivos cgroup
y task_profile
en este orden:
- Archivos
cgroups.json
ytask_profiles.json
predeterminados. - Archivos específicos del nivel de API, si están presentes.
- Archivos de partición del proveedor, si están presentes.
Cambios en la API existente
Android 10 y versiones posteriores mantienen 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 funciones relacionadas con cgroup.
Aunque el encabezado cutils/sched_policy.h
todavía existe, para evitar romper el código existente, asegúrese de que el nuevo código incluya un nuevo encabezado processgroup/sched_policy.h
.
Los módulos que utilizan cualquiera de estas funciones deben agregar dependencia de la biblioteca libprocessgroup
en su archivo MAKE. Si un módulo no utiliza ninguna otra funcionalidad libcutils
, elimine la dependencia de la biblioteca libcutils
del archivo MAKE.
API de perfiles de tareas
Las API privadas en processgroup/processgroup.h
se definen en la tabla:
Tipo | API y definición |
---|---|
bool | SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles) Aplica los perfiles de tarea especificados en profiles al subproceso especificado por un ID de subproceso (tid) utilizando su parámetro tid . |
bool | SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) Aplica los perfiles de tarea especificados en profiles al proceso especificado por su usuario y sus ID de proceso utilizando los parámetros uid y pid |
bool | CgroupGetControllerPath(const std::string& cgroup_name, std::string* path) Devuelve si existe un controlador 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) Devuelve si existe un atributo de perfil especificado por attr_name ; Si es true , establece la variable path en la ruta del archivo asociado con ese atributo de perfil. |
bool | CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path) Devuelve si existe un atributo de perfil especificado por attr_name ; Si true , establece la variable path en la ruta del archivo asociado con ese atributo de perfil y en el hilo especificado por su ID de hilo usando el parámetro tid . |
bool | UsePerAppMemcg() Devuelve si el sistema está configurado para utilizar grupos de memoria por aplicación. |