การเปลี่ยนแปลง ION ABI

อุปกรณ์ที่ใช้เคอร์เนล 4.14 ขึ้นไปจะได้รับผลกระทบจากการรีแฟกทอริงครั้งใหญ่ของโมดูลเคอร์เนล ION ซึ่งการนำไปใช้งานเลเยอร์การแยกแยะฮาร์ดแวร์ (HAL) ของตัวจัดสรรหน่วยความจำกราฟิก (gralloc) ของหลายผู้ให้บริการจะเรียกใช้เพื่อจัดสรรบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน หน้านี้มีคำแนะนำเกี่ยวกับการย้ายข้อมูลโค้ดของผู้ให้บริการเดิมไปยัง ION เวอร์ชันใหม่ และกล่าวถึงช่วงพักของแอปพลิเคชันแบบไบนารีอินเทอร์เฟซ (ABI) ที่อาจเกิดขึ้นในอนาคต

เกี่ยวกับ ION

ION เป็นส่วนหนึ่งของการพัฒนาอย่างต่อเนื่องของเคอร์เนลอัปสตรีม ต้นไม้สแต็ก ขณะอยู่ในระยะเตรียมความพร้อม ABI จากพื้นที่ผู้ใช้ไปยังเคอร์เนลของ ION อาจมีการหยุดทำงานระหว่างเวอร์ชันหลักของเคิร์นัล แม้ว่าช่วงพักของ ION ABI จะมีผลโดยตรงต่อแอปทั่วไปหรืออุปกรณ์ที่เปิดใช้งานแล้ว แต่ผู้ให้บริการที่ย้ายข้อมูลไปยังเคอร์เนลเวอร์ชันหลักใหม่อาจพบการเปลี่ยนแปลงที่ส่งผลกระทบต่อการเรียกใช้โค้ดของผู้ให้บริการใน ION นอกจากนี้ การหยุดทำงานของ ABI อาจเกิดขึ้นในอนาคตเมื่อทีมระบบ Android ทำงานร่วมกับทีมที่ดูแลเวอร์ชันที่พัฒนาขึ้นเพื่อย้าย ION ออกจากต้นไม้สแต็ก

การเปลี่ยนแปลงใน android-4.14

Kernel 4.12 เปลี่ยนโครงสร้างภายในโค้ดเคอร์เนล ION อย่างหนัก โดยทำความสะอาดและนำส่วนต่างๆ ของ ION ที่ทับซ้อนกับเฟรมเวิร์กเคอร์เนลอื่นๆ ออก ด้วยเหตุนี้ ION ioctl เดิมจำนวนมากจึงไม่มีการใช้งานแล้วและถูกนำออก

การนำไคลเอ็นต์และแฮนเดิล ION ออก

ก่อนเคอร์เนล 4.12 การเปิด /dev/ion จะจัดสรรไคลเอ็นต์ ION ION_IOC_ALLOC ioctl จัดสรรบัฟเฟอร์ใหม่และส่งกลับไปยังพื้นที่ผู้ใช้เป็นแฮนเดิล ION (จำนวนเต็มทึบแสงที่มีความหมายต่อไคลเอ็นต์ ION ที่จัดสรรเท่านั้น) หากต้องการแมปบัฟเฟอร์ไปยังพื้นที่ผู้ใช้หรือแชร์กับกระบวนการอื่นๆ ระบบจะส่งออกแฮนเดิล ION อีกครั้งเป็น fds ของ dma-buf โดยใช้ ION_IOC_SHARE ioctl

ในเคอร์เนล 4.12 ION_IOC_ALLOC ioctl จะแสดงผล dma-buf fds โดยตรง นำสถานะแฮนเดิล ION ระดับกลางออก รวมถึง Ioctel ทั้งหมดที่ใช้หรือสร้างแฮนเดิล ION เนื่องจาก dma-buf fds ไม่ได้เชื่อมโยงกับไคลเอ็นต์ ION ที่เฉพาะเจาะจง คุณจึงไม่จำเป็นต้องใช้ ION_IOC_SHARE ioctl อีกต่อไป และระบบได้นําโครงสร้างพื้นฐานของไคลเอ็นต์ ION ทั้งหมดออกแล้ว

การเพิ่ม ioctl ความสอดคล้องกันของแคช

ก่อนเคอร์เนล 4.12 ION มี ION_IOC_SYNC ioctl เพื่อซิงค์ตัวระบุไฟล์กับหน่วยความจำ ioctl นี้มีการบันทึกที่ไม่ดีและไม่ยืดหยุ่น ด้วยเหตุนี้ ผู้ให้บริการหลายรายจึงใช้ ioctl ที่กําหนดเองเพื่อดำเนินการบำรุงรักษาแคช

เคอร์เนล 4.12 แทนที่ ION_IOC_SYNC ด้วย DMA_BUF_IOCTL_SYNC ioctl ที่ระบุไว้ใน linux/dma-buf.h เรียกใช้ DMA_BUF_IOCTL_SYNC ที่จุดเริ่มต้นและจุดสิ้นสุดของการเข้าถึง CPU ทุกครั้ง โดยมี Flag ที่ระบุว่าการเข้าถึงเหล่านี้เป็นการอ่านและ/หรือการเขียน แม้ว่า DMA_BUF_IOCTL_SYNC จะแสดงผลรายละเอียดมากกว่า ION_IOC_SYNC แต่จะช่วยให้พื้นที่ผู้ใช้ควบคุมการดำเนินการบำรุงรักษาแคชที่เกี่ยวข้องได้มากขึ้น

DMA_BUF_IOCTL_SYNC เป็นส่วนหนึ่งของ ABI ที่เสถียรของเคอร์เนลและใช้ได้กับ fd ของ dma-buf ทั้งหมด ไม่ว่า ION จะจัดสรรหรือไม่ก็ตาม

การย้ายข้อมูลรหัสผู้ให้บริการไปยัง android-4.12 ขึ้นไป

สําหรับไคลเอ็นต์ userspace ทีมระบบ Android ขอแนะนําอย่างยิ่งให้ใช้ libion แทนการเรียก ioctl() แบบโค้ดเปิด ใน Android 9 libion จะตรวจจับ ION ABI โดยอัตโนมัติขณะรันไทม์และพยายามมาสก์ความแตกต่างระหว่างเคอร์เนล อย่างไรก็ตาม ฟังก์ชัน libion ที่สร้างหรือใช้ion_user_handle_t แฮนเดิลจะไม่ทำงานอีกต่อไปหลังจากเคอร์เนล 4.12 คุณแทนที่ฟังก์ชันเหล่านี้ด้วยการดำเนินการที่เทียบเท่าต่อไปนี้ใน dma-buf fds ได้ ซึ่งใช้งานได้กับเคอร์เนลทุกเวอร์ชันจนถึงปัจจุบัน

การเรียกใช้ ion_user_handle_t แบบเดิม การเรียกใช้ fd ของ dma-buf ที่เทียบเท่า
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 ที่แสดงต่อเคอร์เนลอีกต่อไป คุณต้องแปลงไดรเวอร์ที่เคยใช้ ION Kernel API ในเคอร์เนลกับ ion_import_dma_buf_fd() ให้ใช้DMA-BUF API ในเคอร์เนลกับ dma_buf_get()

การหยุดทำงานของ ION ABI ในอนาคต

ก่อนที่จะย้าย ION ออกจากแผนผังการทดลองใช้ได้ รุ่นเคอร์เนลในอนาคตอาจต้องทำลาย ION ABI อีกครั้ง ทีมระบบ Android ไม่ได้คาดคิดว่าการเปลี่ยนแปลงเหล่านี้จะมีผลต่ออุปกรณ์ที่เปิดตัวด้วย Android เวอร์ชันถัดไป แต่การเปลี่ยนแปลงดังกล่าวอาจส่งผลต่ออุปกรณ์ที่ใช้ Android เวอร์ชันต่อๆ ไป

ตัวอย่างเช่น ชุมชน upstream ได้เสนอให้แยกโหนด /dev/ion รายการเดียวออกเป็นโหนดต่อเฮพหลายรายการ (เช่น /dev/ion/heap0) เพื่อให้อุปกรณ์ใช้นโยบาย SELinux ที่แตกต่างกันกับเฮพแต่ละรายการได้ หากมีการใช้การเปลี่ยนแปลงนี้ในเคอร์เนลรุ่นถัดไป จะทำให้ ION ABI ใช้งานไม่ได้