Modularizar montón de ION para GKI

Muchos OEMs de Android modifican el controlador de kernel de ION por varios motivos, como agregar montones de proveedores y personalizar la administración de la caché (para obtener detalles sobre estas modificaciones, consulta Cómo integrar el asignador de memoria de ION). Para permitir que los OEM retengan esas modificaciones cuando se usa la imagen genérica del kernel (GKI), el kernel común de Android v5.4 presenta un framework para modularizar montones de ION específicos del proveedor mientras se mantiene integrado el controlador de ION principal. En la siguiente figura, se muestra el diseño de la imagen del kernel.

Montones de ION modulares

Figura 1: Controlador de kernel ION modularizado

Los montones ION modulares tienen las siguientes ventajas:

  • El controlador principal de ION puede ser parte de la imagen de GKI, lo que permite que todas las optimizaciones de rendimiento y las correcciones de errores independientes del dispositivo lleguen a todos los dispositivos.
  • El controlador principal de ION en el kernel común puede controlar el registro del montón y administrar la interfaz del espacio de usuario y los clientes del kernel. Los módulos de montón del proveedor solo son necesarios para implementar las operaciones de montón personalizadas.
  • El controlador principal de ION (como parte de la GKI) puede incluir hooks 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 montón de ION de proveedores modulares deben facilitar las transiciones futuras a los montón dmabuf.

Implementación

Los módulos de montón de ION pueden registrar sus propias operaciones dmabuf para anular las que registra el controlador principal de ION. Una operación dmabuf (como get_flags()) que no es compatible con el controlador principal de ION muestra -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 caché (consulta changelist). Los clientes del kernel pueden usar las funciones dma_buf_begin_cpu_access_partial y dma_buf_end_cpu_access_partial para realizar el mantenimiento parcial de la caché.

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

Cambios en el encabezado de la UAPI de ION

El encabezado de la API de espacio de usuario (UAPI) de ION contiene una enumeración ion_heap_id para definir un rango de IDs de montón que pueden usar los montones del proveedor.

 /**
 * 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 de espacio de usuario a determinar si se usan pilas modulares.

Anulación del montón genérico del sistema

El montón del sistema de ION está integrado y es parte de la imagen de GKI para garantizar que cualquier función que necesite acceso a un montón genérico o independiente del dispositivo pueda depender de su existencia. Por lo tanto, no puedes anular el ID del montón de ION_HEAP_SYSTEM. Para crear un montón del sistema personalizado, usa un ID de montón en el rango personalizado (ION_HEAP_CUSTOM_START a ION_HEAP_CUSTOM_END) para realizar asignaciones.