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