Änderungen des Ionen-ABI

Geräte mit Kernel 4.14 und höher sind von einer umfassenden Umgestaltung des Ion-Kernelmoduls betroffen, das von vielen HAL-Implementierungen (Graphic Memory Allocator) (Gralloc) der Hardware aufgerufen wird, um gemeinsam genutzte Speicherpuffer zuzuweisen. Dieser Artikel bietet Anleitungen zur Migration von Code von Legacy-Anbietern auf die neue Version von Ion und erörtert mögliche zukünftige Unterbrechungen der Application Binary Interface (ABI).

Über Ion

Ion ist Teil des Work-in-Progress -Staging-Baums des Upstream-Kernels. Während des Stagings kann es bei Ions Userspace-zu-Kernel-ABI zu Unterbrechungen zwischen den Hauptkernelversionen kommen. Während Ion-ABI-Unterbrechungen keine direkten Auswirkungen auf normale Anwendungen oder bereits gestartete Geräte haben , können Anbieter, die auf neue Hauptkernelversionen migrieren, auf Änderungen stoßen, die sich auf den Aufruf des Anbietercodes in Ion auswirken. Darüber hinaus kann es in Zukunft zu ABI-Unterbrechungen kommen, da das Android-Systemteam mit dem Upstream zusammenarbeitet, um Ion aus dem Staging-Baum zu entfernen.

Änderungen in Android-4.14

Kernel 4.12 hat den Ion-Kernel-Code stark überarbeitet und Teile von Ion bereinigt und entfernt, die sich mit anderen Kernel-Frameworks überschnitten. Infolgedessen sind viele ältere Ion-Ioctls nicht mehr relevant und wurden entfernt.

Entfernung von Ion-Clients und -Handles

Vor Kernel 4.12 wurde beim Öffnen von /dev/ion ein Ion-Client zugewiesen. Der ION_IOC_ALLOC ioctl hat einen neuen Puffer zugewiesen und ihn als Ion-Handle an den Userspace zurückgegeben (eine undurchsichtige Ganzzahl, die nur für den Ion-Client von Bedeutung ist, der ihn zugewiesen hat). Um Puffer dem Userspace zuzuordnen oder sie mit anderen Prozessen zu teilen, wurden Ion-Handles mit dem ioctl ION_IOC_SHARE als dma-buf fds erneut exportiert.

In Kernel 4.12 gibt ION_IOC_ALLOC ioctl direkt dma-buf fds aus. Der Zwischenstatus „Ion Handle“ wurde entfernt, zusammen mit allen Ioctls, die Ion Handles verbrauchen oder erzeugen. Da dma-buf fds nicht an bestimmte Ion-Clients gebunden sind, wird ION_IOC_SHARE ioctl nicht mehr benötigt und die gesamte Ion-Client-Infrastruktur wurde entfernt.

Hinzufügung von Cache-Kohärenz-Ioctls

Vor Kernel 4.12 stellte Ion ein ION_IOC_SYNC ioctl bereit, um den Dateideskriptor mit dem Speicher zu synchronisieren. Dieses Ioctl war schlecht dokumentiert und unflexibel. Aus diesem Grund haben viele Anbieter benutzerdefinierte Ioctls implementiert, um die Cache-Wartung durchzuführen.

Kernel 4.12 ersetzte ION_IOC_SYNC durch das in linux/dma-buf.h definierte DMA_BUF_IOCTL_SYNC ioctl . Rufen Sie DMA_BUF_IOCTL_SYNC zu Beginn und am Ende jedes CPU-Zugriffs auf, wobei Flags angeben, ob es sich bei diesen Zugriffen um Lese- und/oder Schreibzugriffe handelt. Obwohl DMA_BUF_IOCTL_SYNC ausführlicher ist als ION_IOC_SYNC , gibt es dem Benutzerbereich mehr Kontrolle über die zugrunde liegenden Cache-Wartungsvorgänge.

DMA_BUF_IOCTL_SYNC ist Teil der stabilen ABI des Kernels und kann mit allen DMA-BUF-FDs verwendet werden, unabhängig davon, ob sie von Ion zugewiesen wurden oder nicht.

Anbietercode wird auf Android 4.12+ migriert

Für Userspace- Clients empfiehlt das Android-Systems-Team dringend die Verwendung von libion ​​anstelle von ioctl() -Aufrufen mit offener Codierung. Ab Android 9 erkennt libion ​​den Ion-ABI automatisch zur Laufzeit und versucht, etwaige Unterschiede zwischen Kerneln zu maskieren. Allerdings funktionieren alle libion-Funktionen, die ion_user_handle_t Handles erzeugt oder konsumiert haben, nach Kernel 4.12 nicht mehr. Sie können diese Funktionen durch die folgenden äquivalenten Vorgänge auf dma-buf fds ersetzen, die auf allen bisherigen Versionen des Kernels funktionieren.

Legacy-Aufruf ion_user_handle_t Äquivalenter DMA-BUF-FD-Aufruf
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (dieser Aufruf ist bei dma-buf fds nicht erforderlich)
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 (dieser Aufruf ist bei dma-buf fds nicht erforderlich)
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, ...);

Da Ion für In-Kernel- Clients keine Kernel-orientierten APIs mehr exportiert, müssen Treiber, die zuvor die In-Kernel-Kernel-API von Ion mit ion_import_dma_buf_fd() verwendet haben, konvertiert werden, um die In-Kernel-dma-buf-API mit dma_buf_get() zu verwenden.

Future Ion ABI bricht

Bevor Ion aus dem Staging-Baum verschoben werden kann, müssen zukünftige Kernel-Releases möglicherweise die Ion-ABI erneut unterbrechen. Das Android-Systemteam geht nicht davon aus, dass sich diese Änderungen auf Geräte auswirken, die mit der nächsten Android-Version gestartet werden. Solche Änderungen können sich jedoch auf Geräte auswirken, die mit nachfolgenden Android-Versionen gestartet werden.

Beispielsweise hat die Upstream-Community vorgeschlagen, den einzelnen /dev/ion Knoten in mehrere Knoten pro Heap aufzuteilen (z. B. /dev/ion/heap0 ), um Geräten die Anwendung unterschiedlicher SELinux-Richtlinien auf jeden Heap zu ermöglichen. Wenn diese Änderung in einer zukünftigen Kernel-Version implementiert wird, würde sie Ion ABI beschädigen.