อุปกรณ์ที่ใช้เคอร์เนล 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 ใช้งานไม่ได้