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)) |
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.