อุปกรณ์ที่จัดส่งเคอร์เนล 4.14 และสูงกว่าได้รับผลกระทบจากการปรับโครงสร้างใหม่ที่สำคัญของ โมดูลเคอร์เนล Ion ซึ่งผู้จำหน่ายหลายรายใช้ตัวจัดสรรหน่วยความจำกราฟิก (gralloc) hardware abstraction layer (HAL) เพื่อจัดสรรบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน บทความนี้ให้คำแนะนำเกี่ยวกับการโยกย้ายรหัสผู้จำหน่ายแบบเดิมไปยัง Ion เวอร์ชันใหม่ และกล่าวถึงการหยุดทำงานของ Application Binary Interface (ABI) ในอนาคตที่เป็นไปได้
เกี่ยวกับไอออน
ไอออนเป็นส่วนหนึ่งของ แผนผังการทำงานระหว่างดำเนินการของเคอร์เนล อัพสตรีม ในขณะที่อยู่ในการแสดงละคร ABI ของ userspace-to-kernel ของ Ion อาจแตกหักระหว่างเวอร์ชันเคอร์เนลหลัก แม้ว่า การหยุดทำงานของ Ion ABI จะไม่ส่งผลกระทบโดยตรงต่อแอปพลิเคชันทั่วไปหรืออุปกรณ์ที่เปิดตัวแล้ว ผู้จำหน่ายที่ย้ายไปยังเคอร์เนลเวอร์ชันหลักใหม่อาจพบการเปลี่ยนแปลงที่ส่งผลต่อการเรียกโค้ดของผู้จำหน่ายเข้าสู่ Ion นอกจากนี้ การหยุดทำงานของ ABI ในอนาคตอาจเกิดขึ้นเมื่อทีมระบบ Android ทำงานร่วมกับอัปสตรีมเพื่อย้าย Ion ออกจากแผนผังการแสดงละคร
การเปลี่ยนแปลงใน android-4.14
Kernel 4.12 ปรับโครงสร้างโค้ดเคอร์เนล Ion อย่างหนัก โดยทำความสะอาดและลบส่วนของ Ion ที่ทับซ้อนกับเฟรมเวิร์กเคอร์เนลอื่นๆ ด้วยเหตุนี้ ไอออน ioctls แบบเดิมจำนวนมากจึงไม่เกี่ยวข้องอีกต่อไปและถูกลบออกไปแล้ว
การถอดไคลเอนต์ไอออนและที่จับ
ก่อนเคอร์เนล 4.12 การเปิด /dev/ion
จะจัดสรร ไคลเอนต์ Ion ION_IOC_ALLOC
ioctl จัดสรรบัฟเฟอร์ใหม่และส่งคืนไปยังพื้นที่ผู้ใช้เป็น หมายเลขอ้างอิงไอออน (จำนวนเต็มทึบแสงมีความหมายเฉพาะกับไคลเอนต์ Ion ที่จัดสรรบัฟเฟอร์เท่านั้น) ในการแมปบัฟเฟอร์ในพื้นที่ผู้ใช้หรือแชร์กับกระบวนการอื่น Ion Handle จะถูกส่งออกอีกครั้งเป็น dma-buf fds โดยใช้ ION_IOC_SHARE
ioctl
ในเคอร์เนล 4.12 นั้น ION_IOC_ALLOC
ioctl จะส่งออก dma-buf fds โดยตรง สถานะด้ามจับไอออนระดับกลางถูกลบออก พร้อมด้วย ioctls ทั้งหมดที่ใช้หรือสร้างด้ามจับไอออน เนื่องจาก dma-buf fds ไม่ได้เชื่อมโยงกับไคลเอนต์ Ion เฉพาะ ION_IOC_SHARE
ioctl จึงไม่จำเป็นอีกต่อไป และโครงสร้างพื้นฐานไคลเอนต์ Ion ทั้งหมดได้ถูกลบออกแล้ว
การเพิ่มเติม ioctls การเชื่อมโยงกันของแคช
ก่อนเคอร์เนล 4.12 Ion ได้จัดเตรียม ION_IOC_SYNC
ioctl เพื่อซิงโครไนซ์ตัวอธิบายไฟล์กับหน่วยความจำ ioctl นี้ได้รับการบันทึกไว้ไม่ดีและไม่ยืดหยุ่น ด้วยเหตุนี้ ผู้จำหน่ายหลายรายจึงใช้ ioctls แบบกำหนดเองเพื่อดำเนินการบำรุงรักษาแคช
Kernel 4.12 แทนที่ ION_IOC_SYNC
ด้วย DMA_BUF_IOCTL_SYNC ioctl
ที่กำหนดไว้ใน linux/dma-buf.h เรียก DMA_BUF_IOCTL_SYNC
ที่จุดเริ่มต้นและจุดสิ้นสุดของการเข้าถึง CPU ทุกรายการ โดยมีแฟล็กระบุว่าการเข้าถึงเหล่านี้เป็นการอ่านและ/หรือเขียนหรือไม่ แม้ว่า DMA_BUF_IOCTL_SYNC
จะมีรายละเอียดมากกว่า ION_IOC_SYNC
แต่ก็ทำให้พื้นที่ผู้ใช้สามารถควบคุมการดำเนินการบำรุงรักษาแคชพื้นฐานได้มากขึ้น
DMA_BUF_IOCTL_SYNC
เป็นส่วนหนึ่งของ ABI ที่เสถียรของเคอร์เนล และสามารถใช้ได้กับ dma-buf fds ทั้งหมด ไม่ว่า 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 แบบเดิม | การเรียก 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 ไม่ส่งออก API ที่เกี่ยวข้องกับเคอร์เนลอีกต่อไป ไดรเวอร์ที่เคยใช้ Ion kernel API ในเคอร์เนลด้วย ion_import_dma_buf_fd()
จะต้องถูกแปลงเพื่อใช้ dma-buf API ในเคอร์เนล ด้วย dma_buf_get()
ไอออน ABI ในอนาคตจะแตกตัว
ก่อนที่ไอออนจะถูกย้ายออกจากแผนผังการจัดเตรียม การปล่อยเคอร์เนลในอนาคตอาจต้องทำลาย Ion ABI อีกครั้ง ทีมงานระบบ Android ไม่คาดหวังว่า การเปลี่ยนแปลงเหล่านี้จะส่งผลกระทบต่ออุปกรณ์ที่เปิดตัวด้วย Android เวอร์ชันถัดไป แต่การเปลี่ยนแปลงดังกล่าวอาจส่งผลกระทบต่ออุปกรณ์ที่เปิดตัวด้วย Android เวอร์ชันถัดไป
ตัวอย่างเช่น ชุมชนอัปสตรีมได้เสนอให้แยกโหนด /dev/ion
เดียวออกเป็นหลายโหนดต่อฮีป (เช่น /dev/ion/heap0
) เพื่อให้อุปกรณ์ใช้นโยบาย SELinux ที่แตกต่างกันกับแต่ละฮีป หากการเปลี่ยนแปลงนี้ถูกนำไปใช้ในเคอร์เนลในอนาคต จะทำให้ Ion ABI เสียหาย
อุปกรณ์ที่จัดส่งเคอร์เนล 4.14 และสูงกว่าได้รับผลกระทบจากการปรับโครงสร้างใหม่ที่สำคัญของ โมดูลเคอร์เนล Ion ซึ่งผู้จำหน่ายหลายรายใช้ตัวจัดสรรหน่วยความจำกราฟิก (gralloc) hardware abstraction layer (HAL) เพื่อจัดสรรบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน บทความนี้ให้คำแนะนำเกี่ยวกับการโยกย้ายรหัสผู้จำหน่ายแบบเดิมไปยัง Ion เวอร์ชันใหม่ และกล่าวถึงการหยุดทำงานของ Application Binary Interface (ABI) ในอนาคตที่เป็นไปได้
เกี่ยวกับไอออน
ไอออนเป็นส่วนหนึ่งของ แผนผังการทำงานระหว่างดำเนินการของเคอร์เนล อัพสตรีม ในขณะที่อยู่ในการแสดงละคร ABI ของ userspace-to-kernel ของ Ion อาจแตกหักระหว่างเวอร์ชันเคอร์เนลหลัก แม้ว่า การหยุดทำงานของ Ion ABI จะไม่ส่งผลกระทบโดยตรงต่อแอปพลิเคชันทั่วไปหรืออุปกรณ์ที่เปิดตัวแล้ว ผู้จำหน่ายที่ย้ายไปยังเคอร์เนลเวอร์ชันหลักใหม่อาจพบการเปลี่ยนแปลงที่ส่งผลต่อการเรียกโค้ดของผู้จำหน่ายเข้าสู่ Ion นอกจากนี้ การหยุดทำงานของ ABI ในอนาคตอาจเกิดขึ้นเมื่อทีมระบบ Android ทำงานร่วมกับอัปสตรีมเพื่อย้าย Ion ออกจากแผนผังการแสดงละคร
การเปลี่ยนแปลงใน android-4.14
Kernel 4.12 ปรับโครงสร้างโค้ดเคอร์เนล Ion อย่างหนัก โดยทำความสะอาดและลบส่วนของ Ion ที่ทับซ้อนกับเฟรมเวิร์กเคอร์เนลอื่นๆ ด้วยเหตุนี้ ไอออน ioctls แบบเดิมจำนวนมากจึงไม่เกี่ยวข้องอีกต่อไปและถูกลบออกไปแล้ว
การถอดไคลเอนต์ไอออนและที่จับ
ก่อนเคอร์เนล 4.12 การเปิด /dev/ion
จะจัดสรร ไคลเอนต์ Ion ION_IOC_ALLOC
ioctl จัดสรรบัฟเฟอร์ใหม่และส่งคืนไปยังพื้นที่ผู้ใช้เป็น หมายเลขอ้างอิงไอออน (จำนวนเต็มทึบแสงมีความหมายเฉพาะกับไคลเอนต์ Ion ที่จัดสรรบัฟเฟอร์เท่านั้น) ในการแมปบัฟเฟอร์ในพื้นที่ผู้ใช้หรือแชร์กับกระบวนการอื่น Ion Handle จะถูกส่งออกอีกครั้งเป็น dma-buf fds โดยใช้ ION_IOC_SHARE
ioctl
ในเคอร์เนล 4.12 นั้น ION_IOC_ALLOC
ioctl จะส่งออก dma-buf fds โดยตรง สถานะด้ามจับไอออนระดับกลางถูกลบออก พร้อมด้วย ioctls ทั้งหมดที่ใช้หรือสร้างด้ามจับไอออน เนื่องจาก dma-buf fds ไม่ได้เชื่อมโยงกับไคลเอนต์ Ion เฉพาะ ION_IOC_SHARE
ioctl จึงไม่จำเป็นอีกต่อไป และโครงสร้างพื้นฐานไคลเอนต์ Ion ทั้งหมดได้ถูกลบออกแล้ว
การเพิ่มเติม ioctls การเชื่อมโยงกันของแคช
ก่อนเคอร์เนล 4.12 Ion ได้จัดเตรียม ION_IOC_SYNC
ioctl เพื่อซิงโครไนซ์ตัวอธิบายไฟล์กับหน่วยความจำ ioctl นี้ได้รับการบันทึกไว้ไม่ดีและไม่ยืดหยุ่น ด้วยเหตุนี้ ผู้จำหน่ายหลายรายจึงใช้ ioctls แบบกำหนดเองเพื่อดำเนินการบำรุงรักษาแคช
Kernel 4.12 แทนที่ ION_IOC_SYNC
ด้วย DMA_BUF_IOCTL_SYNC ioctl
ที่กำหนดไว้ใน linux/dma-buf.h เรียก DMA_BUF_IOCTL_SYNC
ที่จุดเริ่มต้นและจุดสิ้นสุดของการเข้าถึง CPU ทุกรายการ โดยมีแฟล็กระบุว่าการเข้าถึงเหล่านี้เป็นการอ่านและ/หรือเขียนหรือไม่ แม้ว่า DMA_BUF_IOCTL_SYNC
จะมีรายละเอียดมากกว่า ION_IOC_SYNC
แต่ก็ทำให้พื้นที่ผู้ใช้สามารถควบคุมการดำเนินการบำรุงรักษาแคชพื้นฐานได้มากขึ้น
DMA_BUF_IOCTL_SYNC
เป็นส่วนหนึ่งของ ABI ที่เสถียรของเคอร์เนล และสามารถใช้ได้กับ dma-buf fds ทั้งหมด ไม่ว่า 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 แบบเดิม | การเรียก 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 ไม่ส่งออก API ที่เกี่ยวข้องกับเคอร์เนลอีกต่อไป ไดรเวอร์ที่เคยใช้ Ion kernel API ในเคอร์เนลด้วย ion_import_dma_buf_fd()
จะต้องถูกแปลงเพื่อใช้ dma-buf API ในเคอร์เนล ด้วย dma_buf_get()
ไอออน ABI ในอนาคตจะแตกตัว
ก่อนที่ไอออนจะถูกย้ายออกจากแผนผังการจัดเตรียม การปล่อยเคอร์เนลในอนาคตอาจต้องทำลาย Ion ABI อีกครั้ง ทีมงานระบบ Android ไม่คาดหวังว่า การเปลี่ยนแปลงเหล่านี้จะส่งผลกระทบต่ออุปกรณ์ที่เปิดตัวด้วย Android เวอร์ชันถัดไป แต่การเปลี่ยนแปลงดังกล่าวอาจส่งผลกระทบต่ออุปกรณ์ที่เปิดตัวด้วย Android เวอร์ชันถัดไป
ตัวอย่างเช่น ชุมชนอัปสตรีมได้เสนอให้แยกโหนด /dev/ion
เดียวออกเป็นหลายโหนดต่อฮีป (เช่น /dev/ion/heap0
) เพื่อให้อุปกรณ์ใช้นโยบาย SELinux ที่แตกต่างกันกับแต่ละฮีป หากการเปลี่ยนแปลงนี้ถูกนำไปใช้ในเคอร์เนลในอนาคต จะทำให้ Ion ABI เสียหาย