I dispositivi che distribuiscono il kernel 4.14 e versioni successive sono interessati da un importante refactoring del modulo del kernel Ion , che molte implementazioni HAL (Hardware Abstraction Layer) di allocatori di memoria grafica (gralloc) dei fornitori chiamano per allocare buffer di memoria condivisa. Questo articolo fornisce indicazioni sulla migrazione del codice del fornitore legacy alla nuova versione di Ion e discute le possibili future interruzioni dell'interfaccia binaria dell'applicazione (ABI).
A proposito di Ione
Ion fa parte dell'albero di staging in fase di elaborazione del kernel upstream. Durante la fase di staging, l'ABI dallo spazio utente al kernel di Ion potrebbe interrompersi tra le principali versioni del kernel. Sebbene le interruzioni dell'ABI di Ion non influiscano direttamente né sulle applicazioni ordinarie né sui dispositivi già lanciati , i fornitori che migrano verso nuove versioni principali del kernel potrebbero riscontrare modifiche che influiscono sul codice del fornitore che chiama Ion. Inoltre, potrebbero verificarsi future interruzioni dell'ABI poiché il team dei sistemi Android collabora con l'upstream per spostare Ion fuori dall'albero di staging.
Modifiche in Android-4.14
Il kernel 4.12 ha effettuato un pesante refactoring del codice del kernel di Ion, ripulendo e rimuovendo parti di Ion che si sovrapponevano ad altri framework del kernel. Di conseguenza, molti ioctl Ion legacy non sono più rilevanti e sono stati rimossi.
Rimozione di client e handle Ion
Prima del kernel 4.12, l'apertura /dev/ion
allocava un client Ion . L'ioctl ION_IOC_ALLOC
ha allocato un nuovo buffer e lo ha restituito allo spazio utente come handle Ion (un numero intero opaco significativo solo per il client Ion che lo ha allocato). Per mappare i buffer nello spazio utente o condividerli con altri processi, gli handle di Ion sono stati riesportati come dma-buf fds utilizzando l'ioctl ION_IOC_SHARE
.
Nel kernel 4.12, l'ioctl ION_IOC_ALLOC
restituisce direttamente dma-buf fds. Lo stato intermedio dell'handle di ioni è stato rimosso, insieme a tutti gli ioctl che consumano o producono handle di ioni. Poiché i fd dma-buf non sono legati a client Ion specifici, l'ioctl ION_IOC_SHARE
non è più necessario e tutta l'infrastruttura client Ion è stata rimossa.
Aggiunta di ioctl con coerenza della cache
Prima del kernel 4.12, Ion forniva un ioctl ION_IOC_SYNC
per sincronizzare il descrittore di file con la memoria. Questo ioctl era scarsamente documentato e inflessibile. Di conseguenza, molti fornitori hanno implementato ioctl personalizzati per eseguire la manutenzione della cache.
Il kernel 4.12 ha sostituito ION_IOC_SYNC
con l' DMA_BUF_IOCTL_SYNC ioctl
definito in linux/dma-buf.h . Chiama DMA_BUF_IOCTL_SYNC
all'inizio e alla fine di ogni accesso alla CPU, con flag che specificano se questi accessi sono letture e/o scritture. Sebbene DMA_BUF_IOCTL_SYNC
sia più dettagliato di ION_IOC_SYNC
, offre allo spazio utente un maggiore controllo sulle operazioni di manutenzione della cache sottostanti.
DMA_BUF_IOCTL_SYNC
fa parte dell'ABI stabile del kernel ed è utilizzabile con tutti i fd dma-buf, indipendentemente dal fatto che siano stati allocati o meno da Ion.
Migrazione del codice fornitore ad Android-4.12+
Per i client in spazio utente , il team dei sistemi Android incoraggia fortemente l'uso di libion anziché delle chiamate ioctl()
a codifica aperta. A partire da Android 9, libion rileva automaticamente Ion ABI in fase di esecuzione e tenta di mascherare eventuali differenze tra i kernel. Tuttavia, qualsiasi funzione libion che produceva o consumava gli handle ion_user_handle_t
non funzionerà più dopo il kernel 4.12. È possibile sostituire queste funzioni con le seguenti operazioni equivalenti su dma-buf fds, che funzionano su tutte le versioni del kernel fino ad oggi.
Chiamata legacy ion_user_handle_t | Chiamata equivalente dma-buff fd |
---|---|
ion_alloc(ion_fd, …, &buf_handle) | ion_alloc_fd(ion_fd, ..., &buf_fd) |
ion_share(ion_fd, buf_handle, &buf_fd) | N/A (questa chiamata non è necessaria con dma-buff 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 (questa chiamata non è necessaria con dma-buff fds) |
ion_sync_fd(ion_fd, buf_fd) | If (ion_is_legacy(ion_fd)) |
Per i client in-kernel , poiché Ion non esporta più alcuna API rivolta al kernel, i driver che in precedenza utilizzavano l'API del kernel Ion in-kernel con ion_import_dma_buf_fd()
devono essere convertiti per utilizzare l'API dma-buf in-kernel con dma_buf_get()
.
Il futuro Ion ABI si rompe
Prima che Ion possa essere spostato fuori dall'albero di staging, le future versioni del kernel potrebbero dover interrompere nuovamente l'ABI di Ion. Il team dei sistemi Android non prevede che queste modifiche influenzino il lancio dei dispositivi con la prossima versione di Android, ma tali modifiche potrebbero influire sul lancio dei dispositivi con le versioni Android successive.
Ad esempio, la comunità upstream ha proposto di dividere il singolo nodo /dev/ion
in più nodi per heap (ad esempio, /dev/ion/heap0
) per consentire ai dispositivi di applicare diverse policy SELinux a ciascun heap. Se questa modifica venisse implementata in una futura versione del kernel, interromperebbe Ion ABI.