Android 12 में DMABUF और जीपीयू मेमोरी का हिसाब लगाने की सुविधा लागू करना

इस पेज पर, Android 12 में मेमोरी के हिसाब-किताब से जुड़े अलग-अलग सुधारों के बारे में बताया गया है.

sysfs में डीएमए-बीयूएफ़ आंकड़े

Android 11 और Android 12 में, debugfs को उपयोगकर्ता के बिल्ड में mount नहीं किया जा सकता. इसलिए, डीएमए-बीयूएफ़ आंकड़ों को sysfs में Android 12 में /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 यह रीड-ओनली फ़ाइल, बाइट में DMA-BUF का साइज़ बताती है.

libdmabufinfo एपीआई, हर एक्सपोर्टर और हर बफ़र के आंकड़ों को दिखाने के लिए, डीएमए-बीयूएफ़ sysfs के आंकड़ों को पार्स करता है.

कृपया ध्यान दें कि DMA-BUF एक्सपोर्ट करने वाले कर्नेल ड्राइवर को, DMA-BUF बनाने के लिए 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 का हिस्सा है.

ION के दुनिया भर के आंकड़ों को Android 11 में ट्रैक किया जाता है:

  • हर ION हीप से एक्सपोर्ट किए गए डीएमए-बफ़ का कुल साइज़
  • हर IONहीप में, पहले से असाइन की गई इस्तेमाल न की गई मेमोरी का कुल साइज़

Android 11 में हर ION हीप के आंकड़े दिखाने के लिए कोई इंटरफ़ेस उपलब्ध नहीं है.

इस टेबल में, ION के आंकड़ों के इंटरफ़ेस की तुलना ये ऐप्लिकेशन, Android 12 में डीएमए-बीयूएफ़ हीप फ़्रेमवर्क का इस्तेमाल करने वाले डिवाइसों के लिए उपलब्ध हैं.

Android 11 या Android 12 में ION की सुविधा वाले डिवाइस Android 12 में DMA-BUF हेप के साथ लॉन्च होने वाले डिवाइस
हर हीप ION के आंकड़े कोई नहीं DMA-BUF sysfs के आंकड़ों से पार्स किया गया
एक्सपोर्ट किए गए डीएमए-बफ़ का कुल साइज़ /sys/kernel/ion/total_heap_size_kb
(इसमें ऐसे डीएमए-बीयूएफ़ का साइज़ शामिल नहीं है जिन्हें आयन सूची में शामिल नहीं किए जाने वाले लोग एक्सपोर्ट करते हैं)
डीएमए-बीयूएफ़ 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 कॉम्पोनेंट में, GPU मेमोरी के इस्तेमाल की जानकारी शामिल होती है. यह जानकारी, Memtrack HAL के getMemory() इंटरफ़ेस से मिलती है. kernelUsed कॉम्पोनेंट में, डीएमए-बफ़ मेमोरी का कुल इस्तेमाल शामिल था. हालांकि, Android डिवाइसों के लिए जीपीयू मेमोरी इन वजहों से मिलती है:

  • फ़िज़िकल पेज एलोकेटर का इस्तेमाल करके, जीपीयू ड्राइवर से सीधे तौर पर किए गए एलोकेशन
  • जीपीयू के पते के स्पेस में मैप किए गए डीएमए-बफ़

इसलिए, जीपीयू पता स्पेस में मेमोरी-मैप किए गए डीएमए-बीयूएफ़ कम रैम का हिसाब लगाने पर दो बार घटा दिया गया था. Android 12 में, GPU के पता स्पेस में मैप किए गए डीएमए-बीयूएफ़ के साइज़ का हिसाब लगाने के लिए एक समाधान लागू किया गया है. इसका मतलब है कि खोए हुए रैम के हिसाब लगाने में, इसकी गिनती सिर्फ़ एक बार की जाती है.

समाधान के बारे में यहां जानकारी दी गई है:

  • Memtrack HAL API getMemory() को PID 0 के साथ कॉल करने पर, MemtrackType::GL और MemtrackRecord::FLAG_SMAPS_UNACCOUNTED के लिए, जीपीयू की निजी मेमोरी की कुल वैल्यू को रिपोर्ट करना ज़रूरी है.
  • GL के अलावा किसी अन्य MemtrackType के लिए, PID 0 के साथ कॉल किए जाने पर, getMemory() को काम करना चाहिए. इसके बजाय, यह 0 दिखाना चाहिए.
  • जीपीयू मेमोरी ट्रेसपॉइंट/eBPF समाधान जीपीयू की कुल मेमोरी के लिए, Android 12 खातों में जोड़ा गया. जीपीयू की कुल मेमोरी से जीपीयू की निजी मेमोरी को घटाने पर, जीपीयू के पता स्पेस में मैप किए गए डीएमए-बफ़ का साइज़ मिलता है. इसके बाद, इस वैल्यू का इस्तेमाल, जीपीयू मेमोरी के इस्तेमाल का सही हिसाब लगाकर, लॉस्ट रैम के हिसाब लगाने की सटीक जानकारी पाने के लिए किया जा सकता है.
  • ज़्यादातर Memtrack HAL में totalPss में निजी जीपीयू मेमोरी शामिल होती है लागू है, इसलिए इसे lostRAM से हटाने से पहले इसकी डुप्लीकेट कॉपी हटानी होगी.

लागू किए गए समाधान के बारे में अगले सेक्शन में बताया गया है.

इस्तेमाल न की गई रैम से मेमट्रैक में उतार-चढ़ाव की जानकारी हटाना

अलग-अलग पार्टनर के लिए, Memtrack HAL लागू करने की प्रक्रिया अलग-अलग हो सकती है. इसलिए, जीपीयू मेमोरी एचएएल से totalPSS में शामिल करना हमेशा सही नहीं होता. lostRAM से वैरिएबिलिटी हटाने के लिए, lostRAM के हिसाब से MemtrackType::GRAPHICS और MemtrackType::GL में मौजूद मेमोरी को totalPss से हटा दिया जाता है.

totalPss से MemtrackType::GRAPHICS मेमोरी को हटाकर, इससे बदल दिया गया है 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 से हटा दिया गया है और उसकी जगह निजी जीपीयू मेमोरी (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;

इस्तेमाल न हुई रैम का अपडेट किया गया हिसाब

कुल निजी जीपीयू मेमोरी और एक्सपोर्ट की गई डीएमए बफ़र मेमोरी, दोनों kernelUsed + totalPss में शामिल होती हैं. इसे lostRAM से हटा दिया जाता है. यह यह खोई हुई रैम से, दो बार गिने जाने वाले और Memtrack वैरिएबिलिटी, दोनों को खत्म करता है गणना.

final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();

पुष्टि करें

वीटीएस टेस्ट की मदद से, यह नियम लागू होता है कि Android 12 में लॉन्च होने वाले डिवाइसों पर Linux कर्नेल वर्शन 5.4 या उसके बाद के वर्शन getGpuDeviceInfo() एपीआई.

नए Memtrack HAL API getGpuDeviceInfo() को इस्तेमाल किए जा रहे GPU डिवाइस की जानकारी देनी होगी.

इससे, मेमोरी का बेहतर तरीके से हिसाब लगाया जा सकता है. साथ ही, डीएमए बफ़र और जीपीयू के मेमोरी इस्तेमाल की जानकारी भी देखी जा सकती है. कम रैम और मेमोरी के लिए, मेमट्रैक 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 मेमट्रैक HAL getMemory() API को लागू करें MemtrackType::GL के लिए PID 0 के साथ कॉल करने पर वैश्विक कुल जीपीयू-निजी मेमोरी और MemtrackRecord::FLAG_Smaps_UNACCOUNTED.