שינויי ABI של ION

מכשירים שמשמשים לאריזה בליבה (kernel) 4.14 ואילך מושפעים מארגון מחדש (Refactoring) גדול של מודול הליבה של ION, שהרבה ספקים של הקצאת זיכרון הגרפי (gralloc) בשכבת ההפשטה של החומרה (HAL) מחייבים להקצות חוצצי זיכרון משותפים. בדף הזה מפורטות הנחיות להעברת קוד של ספקים מדור קודם לגרסה החדשה של ION, ומוסבר על שינויים אפשריים עתידיים בממשק הבינארי של האפליקציה (ABI).

מידע על ION

ION הוא חלק מעץ ההמתנה של הליבה ב-upstream, שנמצא בשלבי פיתוח. במהלך ההרצה ב-staging, יכול להיות ש-ABI של ION ממרחב המשתמש לליבה יתקלקל בין גרסאות הליבה הראשיות. כשיש שינויים ב-ION ABI, הם לא משפיעים ישירות על אפליקציות רגילות או על מכשירים שכבר הושקו, אבל ספקים שעוברים לגרסאות הליבה העיקריות החדשות עשויים להיתקל בשינויים שמשפיעים על קוד של ספקים שמפעיל קריאה ל-ION. בנוסף, יכול להיות שיהיו שיבושים עתידיים ב-ABI, כי צוות המערכות של Android עובד עם צוותים ב-upstream כדי להעביר את ION מחוץ לעץ ה-staging.

שינויים ב-android-4.14

ליבה (Kernel 4.12) ביצעה ארגון מחדש בצפיפות של קוד הליבה של ION, והנקה והסירה חלקים ב-ION שחופפים למסגרות ליבה אחרות. כתוצאה מכך, הרבה מאיות ה-ION כבר לא רלוונטיות והוסרו.

הסרה של לקוחות ושל כינויים ב-ION

לפני הליבה 4.12, פתיחת /dev/ion הקצתה לקוח ION. ה-ioctl‏ ION_IOC_ALLOC הקצתה מאגר חדש והחזירה אותו למרחב המשתמש בתור חפץ ION (מספר שלם אטום שיש לו משמעות רק ללקוח ה-ION שהקצה אותו). כדי למפות מאגרים למרחב המשתמש או לשתף אותם עם תהליכים אחרים, ה-handle של ION יוצאו מחדש כ-dma-buf fds באמצעות ה-ioctl‏ ION_IOC_SHARE.

בליבה 4.12, הפונקציה ION_IOC_ALLOC ioctl מפיקה ישירות את dma-buf fds. מצב ה-handle הביניים של ION הוסר, יחד עם כל ה-ioctls שמשתמשים ב-handle של ION או יוצרים אותו. מכיוון ש-dma-buf לא קשורים ללקוחות ION ספציפיים, אין יותר צורך ב-ioctl ION_IOC_SHARE וכל התשתית של לקוח ION הוסרה.

הוספת ioctls של עקביות במטמון

לפני הליבה 4.12, ION סיפק ioctl ‏ION_IOC_SYNC כדי לסנכרן את מתאר הקובץ עם הזיכרון. היוקטל הזה היה מתועד בצורה גרועה ולא גמיש. כתוצאה מכך, ספקים רבים הטמיעו 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 היציב של הליבה, וניתן להשתמש בו עם כל קבצי ה-fd של dma-buf, גם אם הם הוקצו על ידי ION וגם אם לא.

העברת קוד של ספק ל-Android מגרסה 4.12 ואילך

ללקוחות userspace, צוות המערכות של Android ממליץ מאוד להשתמש ב-libion במקום בקריאות ioctl() בקוד פתוח. החל מ-Android 9, libion מזהה באופן אוטומטי את ION ABI בזמן הריצה ומנסה להסוות את ההבדלים בין הליבות. עם זאת, פונקציות libion שייצרו או צרכו פקדים של ion_user_handle_t לא יפעלו יותר אחרי הליבה 4.12. אפשר להחליף את הפונקציות האלה בפעולות המקבילות הבאות על fds של dma-buf, שפועלות בכל הגרסאות של הליבה עד היום.

קריאה מדור קודם של 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_sync_fd(ion_fd, buf_fd);
else
    ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

ללקוחות in-kernel, מכיוון ש-ION כבר לא מייצאת ממשקי API שמיועדים לליבה, צריך להמיר מנהלי התקנים שהשתמשו בעבר ב-API הליבה של ION עם ion_import_dma_buf_fd() כך שישתמשו ב-dma-buf API עם dma_buf_get().

הפסקות עתידיות ב-ION ABI

לפני שאפשר יהיה להעביר את ION מעץ ההמתנה, יכול להיות שגרסאות ליבה עתידיות יצטרכו לשבור שוב את ה-ION ABI. צוות המערכות של Android לא צופה שהשינויים האלה ישפיעו על מכשירים שיושקו עם גרסת Android הבאה, אבל שינויים כאלה עשויים להשפיע על מכשירים שיושקו עם גרסאות Android הבאות.

לדוגמה, קהילת המקור הציעה לפצל את הצומת היחיד /dev/ion למספר צמתים לכל אשכול (לדוגמה, /dev/ion/heap0) כדי לאפשר למכשירים להחיל מדיניות SELinux שונה על כל אשכול. אם השינוי הזה יוטמע בגרסה עתידית של הליבה, הוא יגרום לשיבוש ב-ION ABI.