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.