Alterações Ion ABI

Os dispositivos que enviam o kernel 4.14 e superior são afetados por uma grande refatoração do módulo do kernel Ion , que muitas implementações do alocador de memória gráfica (gralloc) da camada de abstração de hardware (HAL) do fornecedor chamam para alocar buffers de memória compartilhada. Este artigo fornece orientação sobre como migrar o código do fornecedor herdado para a nova versão do Ion e discute possíveis interrupções futuras da interface binária do aplicativo (ABI).

Sobre o Íon

Ion faz parte da árvore de preparação do trabalho em andamento do kernel upstream. Durante a preparação, a ABI do espaço do usuário para o kernel do Ion pode ser interrompida entre as principais versões do kernel. Embora as interrupções do Ion ABI não afetem diretamente os aplicativos comuns ou os dispositivos já lançados , os fornecedores que migram para as novas versões principais do kernel podem encontrar alterações que afetam a chamada do código do fornecedor para o Ion. Além disso, futuras quebras de ABI podem ocorrer enquanto a equipe de sistemas Android trabalha com o upstream para mover o Ion para fora da árvore de preparação.

Mudanças no android-4.14

O Kernel 4.12 refatorou fortemente o código do kernel Ion, limpando e removendo partes do Ion que se sobrepunham a outras estruturas do kernel. Como resultado, muitos Ion ioctls herdados não são mais relevantes e foram removidos.

Remoção de clientes e identificadores Ion

Antes do kernel 4.12, abrir /dev/ion alocava um cliente Ion . O ioctl IOC_ION_ALLOC alocou um novo buffer e o retornou ao espaço do usuário como um identificador Ion (um inteiro opaco significativo apenas para o cliente Ion que o alocou). Para mapear buffers no espaço do usuário ou compartilhá-los com outros processos, os identificadores Ion foram reexportados como dma-buf fds usando o ioctl IOC_ION_SHARE .

No kernel 4.12, o IOC_ION_ALLOC ioctl gera diretamente dma-buf fds. O estado de identificador Ion intermediário foi removido, juntamente com todos os ioctls que consomem ou produzem identificadores Ion. Como os dma-buf fds não estão vinculados a clientes Ion específicos, o ioctl IOC_ION_SHARE não é mais necessário e toda a infraestrutura do cliente Ion foi removida.

Adição de ioctls de coerência de cache

Antes do kernel 4.12, Ion fornecia um ioctl ION_IOC_SYNC para sincronizar o descritor de arquivo com a memória. Este ioctl foi mal documentado e inflexível. Como resultado, muitos fornecedores implementaram ioctls personalizados para executar a manutenção do cache.

O Kernel 4.12 substituiu ION_IOC_SYNC pelo DMA_BUF_IOCTL_SYNC ioctl definido em linux/dma-buf.h . Chame DMA_BUF_IOCTL_SYNC no início e no final de cada acesso à CPU, com sinalizadores especificando se esses acessos são leituras e/ou gravações. Embora DMA_BUF_IOCTL_SYNC seja mais detalhado que ION_IOC_SYNC , ele fornece ao espaço do usuário mais controle sobre as operações de manutenção do cache subjacente.

DMA_BUF_IOCTL_SYNC faz parte da ABI estável do kernel e pode ser usado com todos os dma-buf fds, sejam ou não alocados por Ion.

Migrando o código do fornecedor para android-4.12+

Para clientes de espaço de usuário , a equipe de sistemas Android incentiva fortemente o uso de libion ​​em vez de chamadas ioctl() de código aberto. A partir do Android 9, o libion ​​detecta automaticamente o Ion ABI em tempo de execução e tenta mascarar quaisquer diferenças entre os kernels. No entanto, quaisquer funções libion ​​que produziam ou consumiam identificadores ion_user_handle_t não funcionam mais após o kernel 4.12. Você pode substituir essas funções pelas seguintes operações equivalentes em dma-buf fds, que funcionam em todas as versões do kernel até o momento.

Chamada ion_user_handle_t herdada Chamada equivalente dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (esta chamada não é necessária com dma-buf fds)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) N/A (esta chamada não é necessária com dma-buf fds)
ion_sync_fd(ion_fd, buf_fd) If (ion_is_legacy(ion_fd))

ion_sync_fd(ion_fd, buf_fd);

else

ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

Para clientes no kernel , como o Ion não exporta mais nenhuma API voltada para o kernel, os drivers que usaram anteriormente a API do kernel Ion no kernel com ion_import_dma_buf_fd() devem ser convertidos para usar a API dma-buf no kernel com dma_buf_get() .

Futuras quebras Ion ABI

Antes que o Ion possa ser movido para fora da árvore de preparação, as versões futuras do kernel podem precisar quebrar o Ion ABI novamente. A equipe de sistemas Android não espera que essas alterações afetem os dispositivos lançados com a próxima versão do Android, mas essas alterações podem afetar os dispositivos lançados com as versões subsequentes do Android.

Por exemplo, a comunidade upstream propôs dividir o único nó /dev/ion em vários nós por heap (por exemplo, /dev/ion/heap0 ) para permitir que os dispositivos apliquem diferentes políticas SELinux a cada heap. Se essa alteração for implementada em uma versão futura do kernel, ela interromperá o Ion ABI.

,

Os dispositivos que enviam o kernel 4.14 e superior são afetados por uma grande refatoração do módulo do kernel Ion , que muitas implementações do alocador de memória gráfica (gralloc) da camada de abstração de hardware (HAL) do fornecedor chamam para alocar buffers de memória compartilhada. Este artigo fornece orientação sobre como migrar o código do fornecedor herdado para a nova versão do Ion e discute possíveis interrupções futuras da interface binária do aplicativo (ABI).

Sobre o Íon

Ion faz parte da árvore de preparação do trabalho em andamento do kernel upstream. Durante a preparação, a ABI do espaço do usuário para o kernel do Ion pode ser interrompida entre as principais versões do kernel. Embora as interrupções do Ion ABI não afetem diretamente os aplicativos comuns ou os dispositivos já lançados , os fornecedores que migram para as novas versões principais do kernel podem encontrar alterações que afetam a chamada do código do fornecedor para o Ion. Além disso, futuras quebras de ABI podem ocorrer enquanto a equipe de sistemas Android trabalha com o upstream para mover o Ion para fora da árvore de preparação.

Mudanças no android-4.14

O Kernel 4.12 refatorou fortemente o código do kernel Ion, limpando e removendo partes do Ion que se sobrepunham a outras estruturas do kernel. Como resultado, muitos Ion ioctls herdados não são mais relevantes e foram removidos.

Remoção de clientes e identificadores Ion

Antes do kernel 4.12, abrir /dev/ion alocava um cliente Ion . O ioctl IOC_ION_ALLOC alocou um novo buffer e o retornou ao espaço do usuário como um identificador Ion (um inteiro opaco significativo apenas para o cliente Ion que o alocou). Para mapear buffers no espaço do usuário ou compartilhá-los com outros processos, os identificadores Ion foram reexportados como dma-buf fds usando o ioctl IOC_ION_SHARE .

No kernel 4.12, o IOC_ION_ALLOC ioctl gera diretamente dma-buf fds. O estado de identificador Ion intermediário foi removido, juntamente com todos os ioctls que consomem ou produzem identificadores Ion. Como os dma-buf fds não estão vinculados a clientes Ion específicos, o ioctl IOC_ION_SHARE não é mais necessário e toda a infraestrutura do cliente Ion foi removida.

Adição de ioctls de coerência de cache

Antes do kernel 4.12, Ion fornecia um ioctl ION_IOC_SYNC para sincronizar o descritor de arquivo com a memória. Este ioctl foi mal documentado e inflexível. Como resultado, muitos fornecedores implementaram ioctls personalizados para executar a manutenção do cache.

O Kernel 4.12 substituiu ION_IOC_SYNC pelo DMA_BUF_IOCTL_SYNC ioctl definido em linux/dma-buf.h . Chame DMA_BUF_IOCTL_SYNC no início e no final de cada acesso à CPU, com sinalizadores especificando se esses acessos são leituras e/ou gravações. Embora DMA_BUF_IOCTL_SYNC seja mais detalhado que ION_IOC_SYNC , ele fornece ao espaço do usuário mais controle sobre as operações de manutenção do cache subjacente.

DMA_BUF_IOCTL_SYNC faz parte da ABI estável do kernel e pode ser usado com todos os dma-buf fds, sejam ou não alocados por Ion.

Migrando o código do fornecedor para android-4.12+

Para clientes de espaço de usuário , a equipe de sistemas Android incentiva fortemente o uso de libion ​​em vez de chamadas ioctl() de código aberto. A partir do Android 9, o libion ​​detecta automaticamente o Ion ABI em tempo de execução e tenta mascarar quaisquer diferenças entre os kernels. No entanto, quaisquer funções libion ​​que produziam ou consumiam identificadores ion_user_handle_t não funcionam mais após o kernel 4.12. Você pode substituir essas funções pelas seguintes operações equivalentes em dma-buf fds, que funcionam em todas as versões do kernel até o momento.

Chamada ion_user_handle_t herdada Chamada equivalente dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (esta chamada não é necessária com dma-buf fds)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) N/A (esta chamada não é necessária com dma-buf fds)
ion_sync_fd(ion_fd, buf_fd) If (ion_is_legacy(ion_fd))

ion_sync_fd(ion_fd, buf_fd);

else

ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

Para clientes no kernel , como o Ion não exporta mais nenhuma API voltada para o kernel, os drivers que usaram anteriormente a API do kernel Ion no kernel com ion_import_dma_buf_fd() devem ser convertidos para usar a API dma-buf no kernel com dma_buf_get() .

Futuras quebras Ion ABI

Antes que o Ion possa ser movido para fora da árvore de preparação, as versões futuras do kernel podem precisar quebrar o Ion ABI novamente. A equipe de sistemas Android não espera que essas alterações afetem os dispositivos lançados com a próxima versão do Android, mas essas alterações podem afetar os dispositivos lançados com as versões subsequentes do Android.

Por exemplo, a comunidade upstream propôs dividir o único nó /dev/ion em vários nós por heap (por exemplo, /dev/ion/heap0 ) para permitir que os dispositivos apliquem diferentes políticas SELinux a cada heap. Se essa alteração for implementada em uma versão futura do kernel, ela interromperá o Ion ABI.