Изменения Ион ABI

Устройства, поставляющие ядро ​​4.14 и выше, затронуты серьезным рефакторингом модуля ядра Ion , который многие реализации уровня аппаратной абстракции (HAL) распределителя графической памяти (gralloc) от многих производителей вызывают для выделения буферов общей памяти. В этой статье представлены рекомендации по переносу устаревшего кода поставщика в новую версию Ion и обсуждаются возможные будущие разрывы двоичного интерфейса приложений (ABI).

О Ионе

Ion является частью промежуточного дерева незавершенной работы ядра. Во время промежуточной подготовки ABI Ion от пользовательского пространства к ядру может прерываться между основными версиями ядра. Хотя перерывы в Ion ABI не влияют напрямую ни на обычные приложения, ни на уже запущенные устройства , поставщики, мигрирующие на новые основные версии ядра, могут столкнуться с изменениями, которые влияют на вызов кода поставщика в Ion. Кроме того, в будущем могут возникнуть сбои в ABI, поскольку системная группа Android работает с вышестоящими специалистами над перемещением Ion из промежуточного дерева.

Изменения в андроид-4.14

Ядро 4.12 подвергло серьезному рефакторингу код ядра Ion, очистив и удалив части Ion, которые пересекались с другими платформами ядра. В результате многие устаревшие ioctl Ion больше не актуальны и были удалены.

Удаление клиентов и дескрипторов Ion

До ядра 4.12 при открытии /dev/ion выделялся клиент Ion . ION_IOC_ALLOC ioctl выделил новый буфер и вернул его в пространство пользователя в качестве дескриптора Ion (непрозрачное целое число, имеющее значение только для клиента Ion, который его выделил). Чтобы сопоставить буферы с пользовательским пространством или поделиться ими с другими процессами, дескрипторы Ion были повторно экспортированы как dma-buf fds с использованием ioctl ION_IOC_SHARE .

В ядре 4.12 ioctl ION_IOC_ALLOC напрямую выводит dma-buf fds. Промежуточное состояние дескриптора Ion было удалено вместе со всеми ioctl, которые потребляют или создают дескрипторы Ion. Поскольку dma-buf fds не привязаны к конкретным клиентам Ion, ioctl ION_IOC_SHARE больше не нужен, и вся клиентская инфраструктура Ion была удалена.

Добавление ioctls когерентности кэша

До ядра 4.12 Ion предоставлял ioctl ION_IOC_SYNC для синхронизации дескриптора файла с памятью. Этот ioctl был плохо документирован и негибок. В результате многие поставщики внедрили специальные ioctl для обслуживания кэша.

В ядре 4.12 ION_IOC_SYNC заменен на DMA_BUF_IOCTL_SYNC ioctl , определенный в linux/dma-buf.h . Вызов DMA_BUF_IOCTL_SYNC в начале и конце каждого доступа к ЦП с флагами, определяющими, являются ли эти доступы чтением и/или записью. Хотя DMA_BUF_IOCTL_SYNC является более подробным, чем ION_IOC_SYNC , он дает пользовательскому пространству больше контроля над базовыми операциями обслуживания кэша.

DMA_BUF_IOCTL_SYNC является частью стабильного ABI ядра и может использоваться со всеми dma-buf fds, независимо от того, были ли они выделены Ion.

Перенос кода поставщика на Android-4.12+

Для клиентов пользовательского пространства команда систем Android настоятельно рекомендует использовать libion , а не вызовы ioctl() с открытым кодом. Начиная с Android 9, libion ​​автоматически обнаруживает Ion ABI во время выполнения и пытается замаскировать любые различия между ядрами. Однако любые функции libion, которые создавали или использовали ion_user_handle_t , больше не работают после ядра 4.12. Вы можете заменить эти функции следующими эквивалентными операциями с dma-buf fds, которые на сегодняшний день работают во всех версиях ядра.

Устаревший вызов ion_user_handle_t Эквивалентный вызов dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) Н/Д (этот вызов не нужен для dma-buf 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) Н/Д (этот вызов не нужен для dma-buf fds)
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, ...);

Для клиентов внутри ядра , поскольку Ion больше не экспортирует API-интерфейсы, ориентированные на ядро, драйверы, которые ранее использовали API ядра Ion с ion_import_dma_buf_fd() , должны быть преобразованы для использования API dma-buf внутри ядра с dma_buf_get() .

Будущие перерывы в Ion ABI

Прежде чем Ion можно будет удалить из промежуточного дерева, в будущих выпусках ядра, возможно, потребуется снова сломать Ion ABI. Команда систем Android не ожидает, что эти изменения повлияют на запуск устройств со следующей версией Android, но такие изменения могут повлиять на запуск устройств с последующими версиями Android.

Например, сообщество разработчиков upstream предложило разделить один узел /dev/ion на несколько узлов по куче (например, /dev/ion/heap0 ), чтобы устройства могли применять разные политики SELinux к каждой куче. Если это изменение будет реализовано в будущем выпуске ядра, это нарушит работу Ion ABI.