Camada de abstração Cgroup

O Android 10 e versões mais recentes usam um grupo de controle (cgroup) camada de abstração com perfis de tarefas, que os desenvolvedores podem usar para descrever um conjunto (ou conjuntos) de restrições a serem aplicadas a uma linha de execução ou a um processo. Em seguida, o sistema siga as ações prescritas dos perfis de tarefas para selecionar um ou mais os cgroups apropriados, pelos quais as restrições são aplicadas, e alterações na o conjunto de recursos do cgroup pode ser criado sem afetar softwares superiores camadas.

Sobre os cgroups

Os cgroups fornecem um mecanismo para agregar e particionar conjuntos de tarefas. (que consistem em processos, linhas de execução e todos os filhos futuros deles) em grupos hierárquicos com comportamento especializado. O Android usa cgroups para controlar e considerar recursos do sistema, como uso e alocação de memória e CPU, com suporte para Kernel do Linux cgroups v1 e cgroups v2.

Android 9 e versões anteriores

No Android 9 e versões anteriores, o script de inicialização init.rc continha o conjunto de os cgroups disponíveis, os pontos de montagem e as versões. Embora possam ser mudava, o framework do Android esperava que um conjunto específico de cgroups existisse locais específicos com uma determinada versão e hierarquia de subgrupos, com base na script. Isso limitava a capacidade de escolher a próxima versão do cgroup a ser usada ou alterar a hierarquia do cgroup para usar novos atributos;

Android 10 e versões mais recentes

O Android 10 e versões mais recentes usam cgroups com perfis de tarefas:

  • Configuração do Cgroup. Os desenvolvedores descrevem a configuração dos cgroups no cgroups.json para definir conjuntos de cgroups e os locais e atributos de montagem deles. Todos os cgroups são montados durante o estágio de inicialização inicial da inicialização. de desenvolvimento de software.
  • Perfis de tarefas. Elas fornecem uma abstração que separa os componentes a funcionalidade nos detalhes da implementação. O framework do Android aplica os perfis de tarefa conforme descrito no arquivo task_profiles.json a um ou linha de execução usando as APIs SetTaskProfiles e SetProcessProfiles. Essas APIs são exclusivas do Android 11 e versões mais recentes.

Para oferecer compatibilidade com versões anteriores, as funções legadas set_cpuset_policy, set_sched_policy e get_sched_policy oferecem a mesma API e funcionalidade, mas sua implementação foi modificada para usar perfis de tarefas. Para novos usos casos, o AOSP recomenda o uso de novas APIs de perfis de tarefas em vez das APIs legadas função set_sched_policy.

Arquivo de descrição de Cgroups

Os Cgroups são descritos em cgroups.json. localizado em <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Cada controlador é descrito em uma subseção e deve ter pelo menos os seguintes itens:

  • Nome, definido pelo campo Controller.
  • Caminho de montagem, definido pelo campo Path.
  • Modo, UID (ID do usuário) e GID (ID de grupo) que descrevem o proprietário e modos de acesso para os arquivos nesse caminho (todos opcionais).
  • Atributo opcional, definido como true para permitir que o sistema ignore a montagem erro causado por um controlador cgroup que o kernel não suporta ser montado.

Exemplo de arquivo cgroups.json

O exemplo abaixo mostra descrições para o cgroup v1 (Cgroups) e o cgroup v2 (Cgroups2) pelos respectivos caminhos.

{
  "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 arquivo de exemplo contém duas seções, Cgroups (que descrevem o cgroup v1 controladores) e Cgroups2 (que descrevem os controladores cgroup v2). Todos os controladores na hierarquia de cgroups v2 são montados no mesmo local. Portanto, a seção Cgroups2 tem seus próprios Caminho, Modo, UID e GID para descrever o local e os atributos da raiz do hierarquia. O atributo Path para Controladores em Cgroups2 é em relação ao caminho raiz. No Android 12 e versões mais recentes, é possível definir um cgroup controlador especificado com o caminho e modo como "Optional" definindo-o como true.

O arquivo cgroups.json é analisado como parte do processo init, e os cgroups são montados nos locais especificados. Para obter mais tarde os locais de montagem do cgroup, use a função da API CgroupGetControllerPath.

Arquivo de perfis de tarefas

O task_profiles.json está localizado em <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. Use-o para descrever um conjunto específico de ações a serem aplicadas a um processo ou fio Um conjunto de ações está associado a um nome de perfil, que é usado em Chamadas SetTaskProfiles e SetProcessProfiles para invocar ações do perfil.

Exemplo de arquivo 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" ]
     }
}

Atribua nomes a arquivos cgroup específicos como entradas na lista Atributos. Cada entrada contém o seguinte:

  • O campo Nome especifica o nome do atributo.
  • O campo Controller faz referência a um controlador cgroup do cgroups.json , pelo nome dele.
  • O campo File nomeia um arquivo específico neste controlador.

Atributos são referências nas definições de perfis de tarefas. Fora da tarefa perfis, use-os somente quando o framework exigir acesso direto a eles e o acesso não podem ser abstraídos usando perfis de tarefas. Em todos os outros casos, usar perfis de tarefas; proporcionam uma melhor separação entre o comportamento exigido e os detalhes de implementação.

A seção Perfis contém definições de perfis de tarefas com o seguinte:

  • Nome define o nome do perfil.
  • A seção Ações lista um conjunto de ações realizadas quando o perfil é aplicada. Cada ação tem o seguinte:

    • O campo Name especifica a ação.
    • A seção Params especifica um conjunto de parâmetros para a ação.

As ações compatíveis estão listadas na tabela:

Ação Parâmetro Descrição
SetTimerSlack Slack Tempo livre do timer em ns
SetAttribute Name Um nome que faz referência a um atributo da seção Attributes.
Value Um valor a ser gravado no arquivo representado pelo atributo nomeado
WriteFileFilePathcaminho para o arquivo
Valueum valor a ser gravado no arquivo
JoinCgroup Controller Um nome do controlador do cgroup de cgroups.json
Path Um caminho de subgrupo na hierarquia do controlador do cgroup

O Android 12 e versões mais recentes têm um AggregateProfiles. seção que contém perfis agregados, cada um sendo um alias de um conjunto de um ou mais perfis. As definições de perfil agregado consistem no seguinte:

  • O campo Name especifica o nome do perfil agregado.
  • O campo Perfis lista os nomes dos perfis incluídos no perfil agregado.

Quando um perfil agregado é aplicado, todos os perfis que o contêm também são são aplicadas automaticamente. Os perfis agregados podem conter perfis individuais ou outros perfis agregados, desde que não haja recursões (um perfil que inclui.

comando de linguagem init task_profiles

Um comando task_profiles na linguagem Init do Android está disponível para o Android 12 e versões mais recentes a ativação do perfil de tarefa para um processo específico. Ela substitui writepid. (descontinuado no Android 12) que foi usado para migrar uma entre cgroups. O comando task_profiles oferece flexibilidade para mudando implementações subjacentes sem efeito nas camadas superiores. Na exemplo abaixo, esses dois comandos executam efetivamente a mesma operação:

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

    Descontinuado no Android 12. Ele foi usado para criar o PID da tarefa atual no arquivo /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    Une o processo atual ao grupo top-app em "cpu" controle (cpuctl), o que resulta na gravação do PID do processo para dev/cpuctl/top-app/tasks.

Sempre use o comando task_profiles para migrar tarefas em hierarquias de cgroup na Android 12 e versões mais recentes. Ele aceita um ou mais parâmetros, que representam nomes dos perfis especificados no arquivo task_profiles.json.

Por perfis de tarefa no nível da API

No Android 12 e versões mais recentes, é possível mudar ou substituir definições nos arquivos cgroups.json e task_profiles.json padrão, seja basear a mudança no nível da API do Android ou fazer com que ela seja feita pelo fornecedor partição.

Para substituir as definições com base no nível da API, os seguintes arquivos devem ser presentes no dispositivo:

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

    Use para cgroups específicos de um nível da API.

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

    Use essa opção para perfis específicos de um nível de API.

Para substituir as definições da partição do fornecedor, os seguintes arquivos devem estar presente no dispositivo:

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

Se um atributo ou uma definição de perfil nesses arquivos tiver o mesmo nome de estiver no arquivo padrão, a definição do arquivo (no nível da API ou no nível do fornecedor) substitui a definição do arquivo a definição anterior. As definições no nível do fornecedor substituem definições no nível da API. Se a nova definição tiver um novo nome, o conjunto de atributos ou perfis for alterado com a nova definição.

O sistema Android carrega os arquivos cgroup e task_profile nesta ordem:

  1. cgroups.json padrão e task_profiles.json .
  2. Arquivos específicos de nível da API, se houver.
  3. Arquivos de partição do fornecedor, se houver.

Mudanças na API

O Android 10 e versões mais recentes mantêm as funções set_cpuset_policy, set_sched_policy e get_sched_policy sem mudanças na API. No entanto, o Android 10 move essas funções para libprocessgroup, que agora contém todas as funcionalidades relacionadas ao cgroup.

Embora o cabeçalho cutils/sched_policy.h ainda exista, para evitar erros no código existente, garanta que o novo código inclua uma nova processgroup/sched_policy.h. cabeçalho.

Os módulos que usam qualquer uma dessas funções devem adicionar dependência no libprocessgroup no makefile. Se um módulo não usar nenhum outro libcutils, remova a libcutils dependência de biblioteca do makefile.

APIs de perfis de tarefas

As APIs particulares em processgroup/processgroup.h estão definidas na tabela:

Tipo API e definição
bool SetTaskProfiles(int tid, const std::vector& profiles)
Aplica os perfis de tarefa especificados em profiles à linha de execução especificada por um ID de linha de execução (tid) usando o parâmetro tid.
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles)
Aplica os perfis de tarefa especificados em profiles ao processo especificado pelos IDs de usuário e de processo usando os parâmetros uid e pid
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Retorna se um controlador cgroup especificado por cgroup_name existe. se true, define a variável path para a raiz desse cgroup
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Retorna se existe um atributo de perfil especificado por attr_name. se true, define a variável path para o caminho do arquivo associado a esse atributo de perfil.
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Retorna se existe um atributo de perfil especificado por attr_name. se true, define a variável path para o caminho do arquivo associado a esse atributo de perfil e para o thread especificado por seu ID de thread usando o parâmetro tid.
bool UsePerAppMemcg()
Retorna se o sistema está configurado para usar cgroups de memória por app.