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