Perubahan ABI ION

Perangkat yang mengirimkan kernel 4.14 dan yang lebih tinggi terpengaruh oleh pemfaktoran ulang besar modul kernel ION, yang dipanggil oleh banyak implementasi lapisan abstraksi hardware (HAL) alokator memori grafis (gralloc) vendor untuk mengalokasikan buffering memori bersama. Halaman ini memberikan panduan tentang cara memigrasikan kode vendor lama ke ION versi baru dan membahas kemungkinan gangguan antarmuka biner aplikasi (ABI) di masa mendatang.

Tentang ION

ION adalah bagian dari hierarki staging kernel upstream yang masih dalam proses. Saat dalam staging, ABI userspace-to-kernel ION mungkin terpisah di antara versi kernel utama. Meskipun jeda ION ABI tidak secara langsung memengaruhi aplikasi biasa atau perangkat yang telah diluncurkan, vendor yang bermigrasi ke versi kernel utama baru mungkin mengalami perubahan yang memengaruhi panggilan kode vendor ke ION. Selain itu, jeda ABI di masa mendatang mungkin terjadi karena tim sistem Android bekerja dengan upstream untuk memindahkan ION keluar dari hierarki staging.

Perubahan di android-4.14

Kernel 4.12 melakukan pemfaktoran ulang yang signifikan pada kode kernel ION, membersihkan dan menghapus bagian ION yang tumpang-tindih dengan framework kernel lainnya. Akibatnya, banyak ioctl ION lama tidak lagi relevan dan telah dihapus.

Penghapusan klien dan nama sebutan akun ION

Sebelum kernel 4.12, membuka /dev/ion mengalokasikan klien ION. ION_IOC_ALLOC ioctl mengalokasikan buffering baru dan menampilkannya ke ruang pengguna sebagai ID ION (bilangan bulat buram yang hanya bermakna bagi klien ION yang mengalokasikannya). Untuk memetakan buffering ke ruang pengguna atau membagikannya dengan proses lain, handle ION diekspor ulang sebagai fd dma-buf menggunakan ioctl ION_IOC_SHARE.

Di kernel 4.12, ioctl ION_IOC_ALLOC langsung menghasilkan fds dma-buf. Status handle ION perantara telah dihapus, beserta semua ioctl yang menggunakan atau menghasilkan handle ION. Karena fd dma-buf tidak terikat dengan klien ION tertentu, ION_IOC_SHARE ioctl tidak lagi diperlukan, dan semua infrastruktur klien ION telah dihapus.

Penambahan ioctl koherensi cache

Sebelum kernel 4.12, ION menyediakan ioctl ION_IOC_SYNC untuk menyinkronkan deskriptor file dengan memori. IOCtl ini tidak didokumentasikan dengan baik dan tidak fleksibel. Akibatnya, banyak vendor menerapkan ioctl kustom untuk melakukan pemeliharaan cache.

Kernel 4.12 mengganti ION_IOC_SYNC dengan DMA_BUF_IOCTL_SYNC ioctl yang ditentukan di linux/dma-buf.h. Panggil DMA_BUF_IOCTL_SYNC di awal dan akhir setiap akses CPU, dengan flag yang menentukan apakah akses ini merupakan akses baca dan/atau tulis. Meskipun DMA_BUF_IOCTL_SYNC lebih panjang daripada ION_IOC_SYNC, opsi ini memberi userspace lebih banyak kontrol atas operasi pemeliharaan cache yang mendasarinya.

DMA_BUF_IOCTL_SYNC adalah bagian dari ABI stabil kernel dan dapat digunakan dengan semua fd dma-buf, terlepas dari apakah fd tersebut dialokasikan oleh ION atau tidak.

Memigrasikan kode vendor ke android-4.12+

Untuk klien ruang pengguna, tim sistem Android sangat menyarankan penggunaan libion daripada panggilan ioctl() open-coding. Mulai Android 9, libion secara otomatis mendeteksi ABI ION saat runtime dan mencoba menyamarkan perbedaan di antara kernel. Namun, fungsi libion apa pun yang menghasilkan atau menggunakan handle ion_user_handle_t tidak akan berfungsi lagi setelah kernel 4.12. Anda dapat mengganti fungsi ini dengan operasi setara berikut pada fds dma-buf, yang berfungsi pada semua versi kernel hingga saat ini.

Panggilan ion_user_handle_t lama Panggilan fd dma-buf yang setara
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) T/A (panggilan ini tidak diperlukan dengan 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) T/A (panggilan ini tidak diperlukan dengan 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, ...);

Untuk klien dalam kernel, karena ION tidak lagi mengekspor API yang menghadap kernel, driver yang sebelumnya menggunakan kernel API ION dalam kernel dengan ion_import_dma_buf_fd() harus dikonversi untuk menggunakan API dma-buf dalam kernel dengan dma_buf_get().

Jeda ABI ION mendatang

Sebelum ION dapat dipindahkan dari hierarki staging, rilis kernel mendatang mungkin perlu memecah ION ABI lagi. Tim sistem Android tidak mengharapkan perubahan ini memengaruhi perangkat yang diluncurkan dengan versi Android berikutnya, tetapi perubahan tersebut dapat memengaruhi perangkat yang diluncurkan dengan versi Android berikutnya.

Misalnya, komunitas upstream telah mengusulkan pemisahan satu node /dev/ion menjadi beberapa node per heap (misalnya, /dev/ion/heap0) agar perangkat dapat menerapkan kebijakan SELinux yang berbeda ke setiap heap. Jika perubahan ini diterapkan dalam rilis kernel mendatang, hal ini akan merusak ABI ION.