I dispositivi che supportano il kernel 4.14 e versioni successive sono interessati da un refactoring sostanziale del modulo del kernel ION, chiamato da molte implementazioni del livello di astrazione hardware (HAL) dell'allocatore di memoria grafica (gralloc) dei fornitori per allocare buffer di memoria condivisa. Questa pagina fornisce indicazioni sulla migrazione del codice del fornitore precedente alla nuova versione di ION e illustra eventuali future interruzioni dell'ABI (Application Bin Interface)
Informazioni su ION
ION fa parte dell' albero di gestione temporanea del kernel upstream. Durante lo staging, l'ABI dallo spazio utente al kernel di ION potrebbe essere interrotto tra le versioni principali del kernel. Sebbene le interruzioni dell'ABI di ION non influiscano direttamente sulle app normali o sui dispositivi già lanciati, i fornitori che eseguono la migrazione alle nuove versioni principali del kernel potrebbero riscontrare modifiche che interessano il codice del fornitore che chiama ION. Inoltre, potrebbero verificarsi interruzioni future dell'ABI mentre il team di sistemi Android collabora con l'upstream per rimuovere ION dall'albero di staging.
Modifiche in android-4.14
Il kernel 4.12 ha sottoposto a refactoring il codice del kernel ION, pulendo e rimuovendo parti di ION che si sovrapponevano ad altri framework del kernel. Di conseguenza, molti ioctl ION precedenti non sono più pertinenti e sono stati rimossi.
Rimozione di handle e client ION
Prima del kernel 4.12, l'apertura di /dev/ion
assegnava 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 ION
sono stati re-esportati come fds dma-buf utilizzando l'ioctl ION_IOC_SHARE
.
Nel kernel 4.12, ION_IOC_ALLOC
ioctl restituisce direttamente dma-buf fds. Lo stato dell'handle ION intermedio è stato rimosso, insieme a tutti gli ioctl che utilizzano o producono handle ION. Poiché
gli fds dma-buf non sono legati a client ION specifici, l'ioctl ION_IOC_SHARE
non è più necessario e tutta l'infrastruttura del client ION è stata rimossa.
Aggiunta di ioctl di coerenza della cache
Prima del kernel 4.12, ION forniva un ioctl ION_IOC_SYNC
per
sincronizzare il descrittore file con la memoria. Questo ioctl era poco documentato e poco flessibile. Di conseguenza, molti fornitori hanno implementato ioctl personalizzati per eseguire la manutenzione della cache.
Il kernel 4.12 ha sostituito ION_IOC_SYNC
con
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 fds dma-buf, indipendentemente dal fatto che siano stati allocati o meno da ION.
Migrazione del codice del fornitore ad Android 4.12 e versioni successive
Per i client spazio utente, il team di sistema di Android consiglia vivamente di utilizzare libion anziché le chiamate ioctl()
con codice aperto. A partire da Android 9, libion rileva automaticamente l'ABI di ION in fase di esecuzione e tenta di mascherare eventuali differenze tra i kernel.
Tuttavia, tutte le funzioni libion che hanno prodotto o consumato handle ion_user_handle_t
non funzionano più dopo il kernel 4.12. Puoi sostituire queste funzioni con le seguenti operazioni equivalenti sui fds dma-buf, che funzionano su tutte le versioni del kernel fino ad oggi.
Chiamata ion_user_handle_t legacy | Chiamata fd dma-buf equivalente |
---|---|
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 i fds dma-buf) |
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 i fds dma-buf) |
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, ...); |
Per i client in-kernel, poiché ION non esporta più API rivolte al kernel, i driver che in precedenza utilizzavano l'API kernel ION in-kernel con ion_import_dma_buf_fd()
devono essere convertiti in modo da utilizzare l'API dma-buf in-kernel con dma_buf_get()
.
Future ION ABI breaks
Prima che ION possa essere spostato dall'albero di staging, le release future del kernel potrebbero dover rompere di nuovo l'ABI di ION. Il team dei sistemi Android non si aspetta che queste modifiche influiscano sui dispositivi che verranno lanciati con la prossima versione di Android, ma tali modifiche potrebbero interessare i dispositivi che vengono lanciati con versioni di Android successive.
Ad esempio, la community 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 criteri SELinux diversi a ogni heap. Se questa
modifica viene implementata in una release futura del kernel, l'ABI di ION verrà violata.