इस पेज पर, Android 12 में मेमोरी के हिसाब से किए गए अलग-अलग सुधारों के बारे में बताया गया है.
sysfs में डीएमए-बीयूएफ़ के आंकड़े
Android 11 और Android 12 में, debugfs
को उपयोगकर्ता के बिल्ड में mount नहीं किया जा सकता. इसलिए, Android 12 में /sys/kernel/dmabuf/buffers
डायरेक्ट्री में sysfs
में डीएमए-बफ़ के आंकड़े जोड़े गए हैं.
पाथ | ब्यौरा |
---|---|
/sys/kernel/dmabuf/buffers
|
/sys/kernel/dmabuf/buffers डायरेक्ट्री में, हर डीएमए-बीयूएफ़ की इंटरनल स्थिति का स्नैपशॉट होता है.
/sys/kernel/dmabuf/buffers/<inode_number> में, यूनीक आइनो नंबर <inode_number> वाले डीएमए-बीयूएफ़ के आंकड़े होते हैं.
|
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name
|
इस रीड-ओनली फ़ाइल में, DMA-BUF एक्सपोर्टर का नाम होता है. |
/sys/kernel/dmabuf/buffers/<inode_number>/size
|
यह रीड-ओनली फ़ाइल, बाइट में DMA-BUF का साइज़ बताती है. |
libdmabufinfo
एपीआई, हर एक्सपोर्टर और हर बफ़र के आंकड़े दिखाने के लिए, डीएमए-बीयूएफ़ sysfs
के आंकड़ों को पार्स करता है.
कृपया ध्यान दें कि डीएमए-बीयूएफ़ एक्सपोर्ट करने वाले कर्नेल ड्राइवर को, डीएमए-बीयूएफ़ बनाने के लिए dma_buf_export()
एपीआई को कॉल करने से पहले, struct dma_buf_export_info
के exp_name
फ़ील्ड को एक्सपोर्टर के नाम पर सही तरीके से सेट करना होगा.
libdmabufinfo
और dmabuf_dump
टूल के लिए, यह ज़रूरी है कि वे हर एक्सपोर्टर के आंकड़े इकट्ठा कर सकें. इन आंकड़ों को बाद में, bugreport में दिखाया जाता है.
dmabuf_dump टूल में बदलाव किया गया है, ताकि इस जानकारी को नए आर्ग्युमेंट -b
के साथ आउटपुट किया जा सके.
डीएमए-बीयूएफ़ हीप फ़्रेमवर्क के आंकड़े
GKI 2.0 में ION को बंद किया जा रहा है. इसकी जगह डीएमए-बीयूएफ़ हीप फ़्रेमवर्क का इस्तेमाल किया जाएगा. यह अपस्ट्रीम Linux kernel का हिस्सा है.
Android 11 में, ION के इन ग्लोबल आंकड़ों को ट्रैक किया जाता है:
- हर ION हीप से एक्सपोर्ट किए गए डीएमए-बीयूएफ़ का कुल साइज़
- हर ION हेप में सेव की गई, पहले से तय की गई और इस्तेमाल न की गई मेमोरी का कुल साइज़
Android 11 में, हर ION हेप के आंकड़े दिखाने के लिए कोई इंटरफ़ेस उपलब्ध नहीं है.
यहां दी गई टेबल में, Android 12 में DMA-BUF ढेर फ़्रेमवर्क का इस्तेमाल करने वाले डिवाइसों के लिए, ION के आंकड़ों के इंटरफ़ेस की तुलना उनके मिलते-जुलते इंटरफ़ेस से की गई है.
Android 11 या Android 12 में ION की सुविधा के साथ लॉन्च होने वाले डिवाइस | Android 12 में DMA-BUF हेप के साथ लॉन्च होने वाले डिवाइस | |
---|---|---|
हर हेप के लिए ION के आंकड़े | कोई नहीं | DMA-BUF sysfs के आंकड़ों से पार्स किया गया |
एक्सपोर्ट किए गए डीएमए-बीयूएफ़ का कुल साइज़ | /sys/kernel/ion/total_heap_size_kb
(इसमें ION एक्सपोर्टर के अलावा, अन्य एक्सपोर्टर के एक्सपोर्ट किए गए डीएमए-बीयूएफ़ का साइज़ शामिल नहीं होता) |
डीएमए-बीयूएफ़ sysfs के आंकड़ों से पार्स किया गया
(इसमें एक्सपोर्ट किए गए सभी डीएमए-बीयूएफ़ का साइज़ शामिल है). |
हीप के हिसाब से कुल मेमोरी | /sys/kernel/ion/total_pool_size_kb |
/sys/kernel/dma_heap/total_pool_size_kb |
इस्तेमाल में न आने वाली रैम का हिसाब लगाने की सुविधा को ज़्यादा सटीक बनाना
पहले, इस्तेमाल में न आने वाली रैम का हिसाब इस तरह लगाया जाता था:
फ़ाइनल लॉन्ग lostRAM
= memInfo.getTotalSizeKb(
) - (totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
totalPss
कॉम्पोनेंट में जीपीयू मेमोरी का इस्तेमाल शामिल था. यह डेटा, Memtrack HAL के getMemory() इंटरफ़ेस से मिलता है. kernelUsed
कॉम्पोनेंट में, डीएमए-बफ़ मेमोरी के कुल इस्तेमाल की जानकारी शामिल थी.
हालांकि, Android डिवाइसों के लिए, जीपीयू मेमोरी इनसे मिली:
- फ़िज़िकल पेज एलोकेटर का इस्तेमाल करके, जीपीयू ड्राइवर से सीधे तौर पर किए गए एलोकेशन
- जीपीयू के पते के स्पेस में मैप किए गए डीएमए-बीयूएफ़
इसलिए, जीपीयू के पता स्पेस में मेमोरी-मैप किए गए डीएमए-बफ़ से, रैम के इस्तेमाल का हिसाब लगाते समय दो बार घटाया गया. Android 12 में, जीपीयू के पता स्पेस में मैप किए गए डीएमए-बीयूएफ़ के साइज़ का हिसाब लगाने के लिए एक समाधान लागू किया गया है. इसका मतलब है कि खोए हुए रैम के हिसाब लगाने में, इसकी गिनती सिर्फ़ एक बार की जाती है.
समस्या को हल करने के बारे में यहां बताया गया है:
- Memtrack HAL API
getMemory()
को PID 0 के साथ कॉल करने पर, उसे MemtrackType::GL और MemtrackRecord::FLAG_SMAPS_UNACCOUNTED के लिए, जीपीयू की निजी मेमोरी की कुल वैल्यू बतानी होगी. GL
के अलावा किसी अन्यMemtrackType
के लिए,PID
0
के साथ कॉल किए जाने पर, getMemory() को काम करना चाहिए. इसके बजाय, यह 0 दिखाना चाहिए.- Android 12 में, जीपीयू मेमोरी ट्रेसपॉइंट/eBPF समाधान जोड़ा गया है. यह जीपीयू की कुल मेमोरी के लिए है. जीपीयू की कुल मेमोरी से जीपीयू की निजी मेमोरी को घटाने पर, जीपीयू के पता स्पेस में मैप किए गए डीएमए-बफ़ का साइज़ मिलता है. इसके बाद, इस वैल्यू का इस्तेमाल, GPU मेमोरी के इस्तेमाल का सही हिसाब लगाकर, लॉस्ट रैम के हिसाब लगाने की सटीक जानकारी पाने के लिए किया जा सकता है.
- ज़्यादातर Memtrack HAL के लागू होने पर, निजी GPU मेमोरी को
totalPss
में शामिल किया जाता है. इसलिए,lostRAM
से हटाने से पहले, इसकी डुप्लीकेट कॉपी हटानी होगी.
लागू किए गए समाधान के बारे में अगले सेक्शन में बताया गया है.
इस्तेमाल न की गई रैम से मेमट्रैक में उतार-चढ़ाव की जानकारी हटाना
Memtrack HAL को लागू करने का तरीका, हर पार्टनर के लिए अलग-अलग हो सकता है. इसलिए, HAL के totalPSS
में शामिल GPU मेमोरी हमेशा एक जैसी नहीं होती. lostRAM
से वैरिएबिलिटी हटाने के लिए, lostRAM
के हिसाब से MemtrackType::GRAPHICS
और MemtrackType::GL
में मौजूद मेमोरी को totalPss
से हटा दिया जाता है.
MemtrackType::GRAPHICS
मेमोरी को totalPss
से हटा दिया गया है और ActivityManagerService.java में lostRAM
कैलकुलेशन में totalExportedDmabuf
मेमोरी से बदल दिया गया है, जैसा कि यहां दिखाया गया है:
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
से हटा दिया गया है और ActivityManagerService.java में lostRAM
कैलकुलेशन में, निजी जीपीयू मेमोरी (gpuPrivateUsage
) से बदल दिया गया है, जैसा कि यहां दिखाया गया है:
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;
इस्तेमाल में न आने वाली रैम का अपडेट किया गया हिसाब
कुल निजी जीपीयू मेमोरी और एक्सपोर्ट की गई डीएमए बफ़र मेमोरी, दोनों kernelUsed + totalPss
में शामिल होती हैं. इसे lostRAM
से हटा दिया जाता है. इससे, इस्तेमाल में न होने वाली रैम का हिसाब लगाते समय, दो बार गिनती होने और मेमट्रैक में होने वाली गड़बड़ी, दोनों की समस्याएं खत्म हो जाती हैं.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
पुष्टि करें
वीटीएस टेस्ट इस नियम को लागू करते हैं कि Linux के कर्नेल वर्शन 5.4 या इसके बाद के वर्शन वाले और Android 12 पर काम करने वाले डिवाइसों में, getGpuDeviceInfo() एपीआई काम करता हो.
नए Memtrack HAL API getGpuDeviceInfo()
को इस्तेमाल किए जा रहे जीपीयू डिवाइस के बारे में जानकारी देनी होगी.
इससे, मेमोरी का बेहतर तरीके से हिसाब लगाया जा सकता है. साथ ही, डीएमए बफ़र और जीपीयू के मेमोरी इस्तेमाल की जानकारी भी देखी जा सकती है. रैम और मेमोरी के इस्तेमाल को बेहतर तरीके से ट्रैक करने के लिए, memtrack एआईडीएल एचएएल लागू करें. यह सुविधा, Google की सेवाओं पर निर्भर नहीं करती.
लागू करना
यह सुविधा एआईडीएल मेमट्रैक एचएएल पर निर्भर करती है. साथ ही, Android 12 में इसे लागू करने के निर्देश, कोड में टिप्पणियों के तौर पर शामिल किए गए हैं.
आने वाले समय में रिलीज़ होने वाले वर्शन में, सभी HIDL HAL को AIDL में बदलने का प्लान है.
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 ड्राइवर में ट्रेसपॉइंट इंटिग्रेट करें. साथ ही, MemtrackType::GL और MemtrackRecord::FLAG_SMAPS_UNACCOUNTED के लिए PID 0 के साथ कॉल किए जाने पर, ग्लोबल तौर पर GPU की निजी मेमोरी को सही तरीके से दिखाने के लिए, AIDL memtrack HAL getMemory()
API लागू करें.