Mudanças no Ion ABI

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

Sobre íon

Ion faz parte da árvore de teste de trabalho em andamento do kernel upstream. Durante a preparação, a ABI do espaço do usuário para o kernel do Ion pode quebrar entre as versões principais 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 novas versões principais do kernel podem encontrar alterações que afetam a chamada de código do fornecedor para o Ion. Além disso, futuras quebras de ABI podem ocorrer à medida que a equipe de sistemas Android trabalha com o upstream para mover o Ion para fora da árvore de teste.

Mudanças no android-4.14

O Kernel 4.12 refatorou fortemente o código do kernel do Ion, limpando e removendo partes do Ion que se sobrepunham a outras estruturas do kernel. Como resultado, muitos ioctls legados do Ion 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 ION_IOC_ALLOC alocou um novo buffer e o retornou ao espaço do usuário como um identificador Ion (um número 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 ION_IOC_SHARE .

No kernel 4.12, o ioctl ION_IOC_ALLOC gera diretamente dma-buf fds. O estado intermediário do identificador de íons foi removido, juntamente com todos os ioctls que consomem ou produzem identificadores de íons. Como o dma-buf fds não está vinculado a clientes Ion específicos, o ioctl ION_IOC_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, o 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 realizar 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 flags especificando se esses acessos são leituras e/ou gravações. Embora DMA_BUF_IOCTL_SYNC seja mais detalhado que ION_IOC_SYNC , ele dá ao espaço do usuário mais controle sobre as operações de manutenção de cache subjacentes.

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

Migrando código do fornecedor para Android-4.12+

Para clientes do espaço do 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 produziram ou consumiram 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 dma-buf fd equivalente
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 APIs voltadas para o kernel, os drivers que anteriormente usavam 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 de Ion ABI

Antes que o Ion possa ser movido para fora da árvore de teste, 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 o lançamento de dispositivos com a próxima versão do Android, mas tais alterações podem afetar o lançamento de dispositivos com 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 esta mudança for implementada em uma versão futura do kernel, ela quebraria o Ion ABI.