Cambios de ABI de iones

Los dispositivos que envían el kernel 4.14 y superior se ven afectados por una refactorización importante del módulo del kernel Ion , al que muchas implementaciones de capa de abstracción de hardware (HAL) del asignador de memoria gráfica (gralloc) de proveedores llaman para asignar buffers de memoria compartida. Este artículo proporciona orientación sobre cómo migrar el código de proveedor heredado a la nueva versión de Ion y analiza posibles roturas futuras de la interfaz binaria de aplicaciones (ABI).

Acerca del ion

Ion es parte del árbol de preparación del trabajo en progreso del kernel ascendente. Mientras está en preparación, la ABI del espacio de usuario al kernel de Ion puede interrumpirse entre las principales versiones del kernel. Si bien las interrupciones de Ion ABI no afectan directamente ni a las aplicaciones ordinarias ni a los dispositivos ya lanzados , los proveedores que migran a nuevas versiones principales del kernel pueden encontrar cambios que afecten el código del proveedor que llama a Ion. Además, es posible que se produzcan futuras roturas de ABI a medida que el equipo de sistemas Android trabaje en sentido ascendente para sacar a Ion del árbol de preparación.

Cambios en android-4.14

Kernel 4.12 refactorizó en gran medida el código del kernel de Ion, limpiando y eliminando partes de Ion que se superponían con otros marcos del kernel. Como resultado, muchos Ion ioctl heredados ya no son relevantes y se han eliminado.

Eliminación de clientes y identificadores de Ion.

Antes del kernel 4.12, al abrir /dev/ion se asignaba un cliente Ion . El IOctl ION_IOC_ALLOC asignó un nuevo búfer y lo devolvió al espacio de usuario como un identificador de Ion (un entero opaco significativo solo para el cliente de Ion que lo asignó). Para asignar buffers al espacio de usuario o compartirlos con otros procesos, los identificadores de Ion se reexportaron como dma-buf fds utilizando ION_IOC_SHARE ioctl.

En el kernel 4.12, ION_IOC_ALLOC ioctl genera directamente dma-buf fds. Se eliminó el estado de mango de iones intermedio, junto con todos los ioctls que consumen o producen mangos de iones. Debido a que los dma-buf fds no están vinculados a clientes Ion específicos, ION_IOC_SHARE ioctl ya no es necesario y se eliminó toda la infraestructura del cliente Ion.

Adición de ioctls de coherencia de caché

Antes del kernel 4.12, Ion proporcionaba un ioctl ION_IOC_SYNC para sincronizar el descriptor de archivo con la memoria. Este ioctl estaba mal documentado y era inflexible. Como resultado, muchos proveedores implementaron ioctls personalizados para realizar el mantenimiento de la caché.

El kernel 4.12 reemplazó ION_IOC_SYNC con el DMA_BUF_IOCTL_SYNC ioctl definido en linux/dma-buf.h . Llame DMA_BUF_IOCTL_SYNC al inicio y al final de cada acceso a la CPU, con indicadores que especifican si estos accesos son de lectura y/o escritura. Aunque DMA_BUF_IOCTL_SYNC es más detallado que ION_IOC_SYNC , le da al espacio de usuario más control sobre las operaciones de mantenimiento de caché subyacentes.

DMA_BUF_IOCTL_SYNC es parte de la ABI estable del kernel y se puede utilizar con todos los fds de dma-buf, hayan sido asignados o no por Ion.

Migración del código del proveedor a Android-4.12+

Para los clientes del espacio de usuario , el equipo de sistemas Android recomienda encarecidamente el uso de llamadas libion ​​en lugar de llamadas ioctl() de código abierto. A partir de Android 9, libion ​​detecta automáticamente Ion ABI en tiempo de ejecución e intenta enmascarar cualquier diferencia entre los núcleos. Sin embargo, cualquier función de libion ​​que produjo o consumió identificadores ion_user_handle_t ya no funciona después del kernel 4.12. Puede reemplazar estas funciones con las siguientes operaciones equivalentes en dma-buf fds, que funcionan en todas las versiones del kernel hasta la fecha.

Llamada heredada ion_user_handle_t Llamada 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 llamada no es necesaria con 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 llamada no es necesaria con 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 los clientes en el kernel , debido a que Ion ya no exporta ninguna API orientada al kernel, los controladores que anteriormente usaban la API del kernel de Ion en el kernel con ion_import_dma_buf_fd() deben convertirse para usar la API dma-buf en el kernel con dma_buf_get() .

El futuro Ion ABI se rompe

Antes de que Ion pueda salir del árbol de preparación, es posible que en futuras versiones del kernel sea necesario romper la ABI de Ion nuevamente. El equipo de sistemas Android no espera que estos cambios afecten a los dispositivos que se inician con la próxima versión de Android, pero dichos cambios pueden afectar a los dispositivos que se inician con versiones posteriores de Android.

Por ejemplo, la comunidad ascendente ha propuesto dividir el nodo único /dev/ion en múltiples nodos por montón (por ejemplo, /dev/ion/heap0 ) para permitir que los dispositivos apliquen diferentes políticas SELinux a cada montón. Si este cambio se implementa en una versión futura del kernel, rompería Ion ABI.