דף זה מתאר את שיפורי חשבונאות הזיכרון השונים שהוצגו באנדרואיד 12.
סטטיסטיקות DMA-BUF ב-sysfs
ב-Android 11 ו-Android 12, לא ניתן להרכיב debugfs
ב-User builds. אז סטטיסטיקות DMA-BUF נוספו ל- sysfs
בספריית /sys/kernel/dmabuf/buffers
באנדרואיד 12.
נָתִיב | תיאור |
---|---|
/sys/kernel/dmabuf/buffers | הספרייה /sys/kernel/dmabuf/buffers מכילה תמונת מצב של המצב הפנימי של כל DMA-BUF. /sys/kernel/dmabuf/buffers/<inode_number> מכיל את הנתונים הסטטיסטיים עבור ה-DMA-BUF עם מספר האינוד הייחודי <inode_number> . |
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name | קובץ זה לקריאה בלבד מכיל את השם של יצואן DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size | קובץ זה לקריאה בלבד מציין את גודל ה-DMA-BUF בבתים. |
ה-API של libdmabufinfo
מנתח את הנתונים הסטטיסטיים של DMA-BUF sysfs
כדי לחשוף נתונים סטטיסטיים לכל יצואן ולכל מאגר.
שים לב שמנהלי התקנים של ליבה המייצאים DMA-BUFs חייבים להגדיר את שדה exp_name
של struct dma_buf_export_info
בצורה נכונה לשם היצואן לפני הפעלת ה-API dma_buf_export()
כדי ליצור DMA-BUF. זה נדרש עבור libdmabufinfo
והכלי dmabuf_dump
כדי להפיק נתונים סטטיסטיים לכל יצואן אשר נחשפים לאחר מכן ב-bugreport.
הכלי dmabuf_dump שונה כדי להוציא מידע זה עם ארגומנט חדש, -b
.
נתונים סטטיסטיים עבור מסגרת ה-DMA-BUF heaps
ION ב-GKI 2.0 מובטל לטובת מסגרת ה-DMA-BUF heaps , שהיא חלק מקרנל הלינוקס במעלה הזרם.
הנתונים הסטטיסטיים הגלובליים של ION עוקבים באנדרואיד 11:
- גודל כולל של DMA-BUFs המיוצאים על ידי כל ערימת ION
- גודל כולל של זיכרון שהוקצה מראש שאינו בשימוש המאוחסן על ידי כל ערימת ION
אין ממשק זמין לחשיפת סטטיסטיקות פר-ION באנדרואיד 11.
הטבלה הבאה משווה את ממשקי הנתונים הסטטיסטיים של ION עם מקביליהם עבור מכשירים המשתמשים במסגרת ה-DMA-BUF heap ב-Android 12.
אנדרואיד 11 או מכשירים מושקים עם תמיכה ב-ION באנדרואיד 12 | מכשירים מושקים עם ערימות DMA-BUF באנדרואיד 12 | |
---|---|---|
סטטיסטיקות ION לכל ערמה | אף אחד | מנותח מסטטיסטיקות DMA-BUF sysfs |
גודל כולל של DMA-BUFs שיוצאו | /sys/kernel/ion/total_heap_size_kb (לא כולל את הגודל של DMA-BUFs המיוצאים על ידי יצואנים שאינם ION) | מנותח מסטטיסטיקות DMA-BUF sysfs (כולל את הגודל של כל DMA-BUFs שיוצאו). |
זיכרון כולל מאוחד בערימות | /sys/kernel/ion/total_pool_size_kb | /sys/kernel/dma_heap/total_pool_size_kb |
שפר את דיוק חישוב ה-RAM שאבד
בעבר חישוב ה-RAM האבוד נעשה באופן הבא:
final long lostRAM
= memInfo.getTotalSizeKb(
) - ( totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
רכיב totalPss
כלל את השימוש בזיכרון GPU (מוחזר על ידי ממשק getMemory() של Memtrack HAL). רכיב kernelUsed
כלל את השימוש הכולל בזיכרון DMA-BUF. עם זאת, עבור מכשירי אנדרואיד, זיכרון ה-GPU הגיע מהדברים הבאים:
- הקצאות ישירות שנעשו על ידי מנהל התקן ה-GPU באמצעות מקצה עמודים פיזי
- DMA-BUFs ממופים למרחב הכתובות של GPU
לכן, DMA-BUFs שמופו בזיכרון למרחב הכתובות של ה-GPU הופחתו פעמיים כאשר חושב זיכרון RAM שאבד. אנדרואיד 12 מיישמת פתרון לחישוב הגודל של DMA-BUFs הממופים במרחב הכתובות של ה-GPU, מה שאומר שהוא נלקח בחשבון רק פעם אחת בחישוב זיכרון RAM אבוד.
הפרטים של הפתרון הם כדלקמן:
- ה-Memtrack HAL API
getMemory()
כאשר נקרא עם PID 0 חייב לדווח על סך הזיכרון הפרטי של ה-GPU הגלובלי, עבור MemtrackType::GL ו-MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - getMemory() כאשר נקרא עם
PID
0
עבורMemtrackType
שאינוGL
אסור להיכשל. במקום זאת עליו להחזיר 0. - פתרון נקודת העקיבה/eBPF של זיכרון GPU שנוסף ב-Android 12 מהווה זיכרון GPU הכולל. הפחתת הזיכרון הפרטי הכולל של ה-GPU מכלל זיכרון ה-GPU מספקת את הגודל של DMA-BUFs הממופים למרחב הכתובות של ה-GPU. לאחר מכן ניתן להשתמש בערך כדי לשפר את הדיוק של חישובי זיכרון RAM אבודים על ידי התחשבות נכונה בשימוש בזיכרון ה-GPU.
- זיכרון ה-GPU הפרטי כלול ב-
totalPss
ברוב יישומי Memtrack HAL ולכן יש לבטל כפילות לפני הסרתו מ-lostRAM
.
הפתרון המיושם מפורט בסעיף הבא.
הסר את השונות של Memtrack מ-RAM שאבד
מכיוון שיישומי Memtrack HAL יכולים להשתנות בין שותפים, זיכרון ה-GPU הכלול ב- totalPSS
מה-HAL לא תמיד עקבי. כדי להסיר את השונות מ- lostRAM
, הזיכרון שנכלל ב- MemtrackType::GRAPHICS
ו- MemtrackType::GL
מוסר מ- totalPss
במהלך חישוב lostRAM
.
זיכרון MemtrackType::GRAPHICS
מוסר מ- totalPss
ומוחלף בזיכרון totalExportedDmabuf
בחישוב lostRAM
ב- ActivityManagerService.java כפי שמוצג להלן:
final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb();
. . .
final long dmabufUnmapped = totalExportedDmabuf - dmabufMapped;
. . .
// Account unmapped dmabufs as part of the kernel memory allocations
kernelUsed += dmabufUnmapped;
// Replace Memtrack HAL reported Graphics category with mapped dmabufs
totalPss -= totalMemtrackGraphics;
totalPss += dmabufMapped;
זיכרון MemtrackType::GL
מוסר מ- totalPss
ומוחלף בזיכרון ה-GPU הפרטי ( gpuPrivateUsage
) בחישוב lostRAM
ב- ActivityManagerService.java כפי שמוצג להלן:
final long gpuUsage = Debug.getGpuTotalUsageKb();
. . .
final long gpuPrivateUsage = Debug.getGpuPrivateMemoryKb();
. . .
// Replace the Memtrack HAL-reported GL category with private GPU allocations.
// Count it as part of the kernel memory allocations.
totalPss -= totalMemtrackGl;
kernelUsed += gpuPrivateUsage;
חישוב זיכרון RAM אבוד מעודכן
גם זיכרון ה-GPU הפרטי הכולל וגם סך זיכרון המאגר DMA המיוצא כלולים ב- kernelUsed + totalPss
שהוסר מ- lostRAM
. זה מבטל גם ספירה כפולה וגם שונות של Memtrack מחישוב זיכרון RAM שאבד.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
מַתַן תוֹקֵף
בדיקות VTS אוכפות את הכלל לפיו מכשירים המופעלים באנדרואיד 12 עם גרסת ליבת לינוקס 5.4 ומעלה תומכים ב- getGpuDeviceInfo() API.
Memtrack HAL API חדש getGpuDeviceInfo()
חייב להחזיר מידע על מכשיר ה-GPU שנמצא בשימוש.
זה מספק חשבונאות זיכרון טובה יותר ונראות לתוך חיץ DMA ושימוש בזיכרון GPU. יישם את memtrack AIDL HAL לניהול טוב יותר של זיכרון RAM וזיכרון שאבדו. תכונה זו אינה תלויה בשירותי Google.
יישום
תכונה זו תלויה ב- AIDL Memtrack HAL , והנחיות להטמעתה באנדרואיד 12 כלולים בקוד כהערות.
כל ה-HIDL HALs מתוכננים להיות מומרים ל-AIDL במהדורות עתידיות.
ממשקי ה-API הבאים נוספו ל- core/java/android/os/Debug.java
:
/**
* Return total memory size in kilobytes for exported DMA-BUFs or -1 if
* the DMA-BUF sysfs stats at /sys/kernel/dmabuf/buffers could not be read.
*
* @hide
*/
public static native long getDmabufTotalExportedKb();
/**
* Return memory size in kilobytes allocated for DMA-BUF heap pools or -1 if
* /sys/kernel/dma_heap/total_pools_kb could not be read.
*
* @hide
*/
public static native long getDmabufHeapPoolsSizeKb();
כדי להבטיח שהגרסה שלך תפעל כמתוכנן, שלב את נקודות העקיבה במנהלי ההתקן של ה-GPU שלך, והטמיע את ה-API של AIDL memtrack HAL getMemory()
כדי להחזיר בצורה נכונה את סך הזיכרון הפרטי של ה-GPU הגלובלי כאשר קוראים עם PID 0 עבור MemtrackType::GL ו-MemtrackRecord:: FLAG_SMAPS_UNACCOUNTED.