Modularización de montones de ION para GKI

Muchos OEM de Android modifican el controlador del kernel de ION por varios motivos, como agregar montones de proveedores y personalizar la administración de caché (para obtener detalles sobre estas modificaciones, consulte Integración del asignador de memoria de ION ). Para permitir que los fabricantes de equipos originales conserven dichas modificaciones al usar la imagen genérica del kernel (GKI) , Android Common Kernel v5.4 presenta un marco para modularizar montones de ION específicos del proveedor mientras mantiene el controlador ION central incorporado. La siguiente figura muestra el diseño de la imagen del kernel .

Montones de iones modulares

Figura 1. Controlador kernel ION modularizado

Los montones modulares de ION tienen las siguientes ventajas.

  • El controlador central ION puede ser parte de la imagen GKI, lo que permite que todas las optimizaciones de rendimiento independientes del dispositivo y las correcciones de errores lleguen a todos los dispositivos.
  • El controlador principal de ION en el kernel común puede manejar el registro de montones y administrar la interfaz para el espacio de usuario y los clientes del kernel. Los módulos de almacenamiento dinámico del proveedor solo son necesarios para implementar las operaciones de almacenamiento dinámico personalizadas.
  • El controlador principal de ION (como parte de GKI) puede incluir ganchos para facilitar el seguimiento del uso de la memoria, lo que no era posible cuando cada OEM tenía su propia versión del controlador de ION.
  • Los montones de ION de proveedores modulares deberían facilitar cualquier transición futura a los montones de dmabuf .

Implementar

Los módulos de almacenamiento dinámico ION pueden registrar sus propias operaciones dmabuf para anular las registradas por el controlador ION principal. Una operación dmabuf (como get_flags() ) que no es compatible con el controlador ION principal devuelve -EOPNOTSUPP si la implementación del montón carece de las anulaciones necesarias.

Para mejorar el rendimiento, el controlador dmabuf puede realizar un mantenimiento parcial de la memoria caché (consulte la lista de cambios ). Los clientes del kernel pueden usar las funciones dma_buf_begin_cpu_access_partial y dma_buf_end_cpu_access_partial para realizar un mantenimiento de caché parcial.

El kernel común de Android contiene implementaciones modulares del sistema y montones del asignador de memoria contigua (CMA) para usar como referencia para la modularización del montón.

Cambios en el encabezado ION UAPI

El encabezado de la API de espacio de usuario de ION (UAPI) contiene una enumeración ion_heap_id para usar en la definición de un rango de ID de almacenamiento dinámico para uso de los almacenamientos dinámicos de proveedores.

 /**
 * ion_heap_id - list of heap IDs that Android can use
 *
 * @ION_HEAP_SYSTEM        ID for the ION_HEAP_TYPE_SYSTEM
 * @ION_HEAP_DMA_START     Start of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
 * @ION_HEAP_DMA_END       End of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
 * @ION_HEAP_CUSTOM_START  Start of reserved ID range for heaps of custom type
 * @ION_HEAP_CUSTOM_END    End of reserved ID range for heaps of custom type
 */

enum ion_heap_id {

   ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM),

   ION_HEAP_DMA_START = (ION_HEAP_SYSTEM << 1),

   ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7),
   ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1),

   ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 22),
};

Además, un nuevo IOCTL ( ION_IOC_ABI_VERSION ) puede ayudar a los clientes del espacio de usuario a determinar si se están utilizando montones modulares.

Anulando el montón del sistema genérico

El montón del sistema ION está integrado y es parte de la imagen de GKI para garantizar que cualquier característica que necesite acceso a un montón genérico/independiente del dispositivo pueda depender de su existencia. Como tal, no puede anular el ID de almacenamiento dinámico de ION_HEAP_SYSTEM . Para crear un montón de sistema personalizado, use un ID de montón en el rango personalizado ( ION_HEAP_CUSTOM_START a ION_HEAP_CUSTOM_END ) para realizar asignaciones.