Na tej stronie opisujemy różne ulepszenia w zakresie zliczania pamięci wprowadzone w Android 12.
Statystyki DMA-BUF w sysfs
W Androidzie 11 i 12 nie można zamontować debugfs
w kompilacji użytkownika. Dlatego statystyki DMA-BUF zostały dodane do sysfs
w
Katalog /sys/kernel/dmabuf/buffers
na Androidzie 12.
Ścieżka | Opis |
---|---|
/sys/kernel/dmabuf/buffers
|
Katalog /sys/kernel/dmabuf/buffers zawiera migawkę stanu wewnętrznego każdego DMA-BUF.
/sys/kernel/dmabuf/buffers/<inode_number> zawiera statystyki:
obiekt DMA-BUF z unikalnym numerem i-węzełowego <inode_number> .
|
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name
|
Ten plik tylko do odczytu zawiera nazwę eksportującego DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size
|
Ten plik tylko do odczytu określa rozmiar DMA-BUF w bajtach. |
libdmabufinfo
Interfejs API analizuje statystyki DMA-BUF sysfs
w celu udostępnienia statystyk dotyczących poszczególnych eksporterów i buforów.
Pamiętaj, że sterowniki jądra, które eksportują pliki DMA-BUF, muszą ustawić exp_name
struct dma_buf_export_info
do nazwy eksportera przed
przez wywołanie interfejsu API dma_buf_export()
w celu utworzenia DMA-BUF.
Jest to wymagane, aby narzędzia libdmabufinfo
i dmabuf_dump
mogły uzyskać statystyki dotyczące poszczególnych eksporterów, które są następnie wyświetlane w bugreport.
Narzędzie dmabuf_dump zostało zmodyfikowane, aby wyświetlać te informacje za pomocą nowego argumentu -b
.
Statystyki dotyczące ramki stosów DMA-BUF
Interfejs ION w GKI 2.0 jest wycofywany i zastępuje platformę stert DMA-BUF, które jest częścią nadrzędnego jądra systemu Linux.
W Androidzie 11 śledzone są te globalne statystyki ION:
- Łączny rozmiar plików DMA-BUF wyeksportowanych przez każdą stertę ION
- Łączny rozmiar nieużywanej wstępnie przydzielonej pamięci przechowywanej przez każdą stertę ION
W Androidzie 11 nie ma interfejsu, który umożliwiłby wyświetlanie statystyk sterty na ION.
W poniższej tabeli porównano interfejsy statystyk ION z ich w przypadku urządzeń korzystających z platformy sterty DMA-BUF w Androidzie 12.
Android 11 lub urządzenia z obsługą funkcji ION w Androidzie 12 | Urządzenia uruchamiane z użyciem stosu DMA-BUF w Androidzie 12 | |
---|---|---|
Statystyki ION dotyczące poszczególnych stosów | Brak | Przetworzone z statystyk sysfs DMA-BUF |
Łączny rozmiar wyeksportowanych plików DMA-BUF | /sys/kernel/ion/total_heap_size_kb .
(nie obejmuje rozmiaru plików DMA-BUF wyeksportowanych przez eksporterów niebędących ION) |
Zanalizowane statystyki sysfs DMA-BUF
(zawiera rozmiar wszystkich wyeksportowanych buforów DMA-BUF). |
Łączna pamięć przypisana stosowi | /sys/kernel/ion/total_pool_size_kb |
/sys/kernel/dma_heap/total_pool_size_kb |
Popraw dokładność obliczania utraconej pamięci RAM
Wcześniej utrata pamięci RAM była obliczana w ten sposób:
końcowy długi czas lostRAM
= memInfo.getTotalSizeKb(
) – (totalPss
– totalSwapPss
)
– memInfo.getFreeSizeKb()
– memInfo.getCachedSizeKb()
– kernelUsed
– memInfo.getZramTotalSizeKb()
;
Komponent totalPss
uwzględniał wykorzystanie pamięci GPU (zwrócone przez
Metoda getMemory() w Memtrack HAL
). Komponent kernelUsed
obejmuje łączne wykorzystanie pamięci DMA-BUF.
W przypadku urządzeń z Androidem pamięć GPU pochodzi z tych źródeł:
- bezpośrednie przydzielenia dokonane przez sterownik GPU za pomocą przydzielacza stron fizycznych;
- Obiekty DMA-BUF zmapowane na przestrzeń adresową GPU
W związku z tym obiekty DMA-BUF zmapowane na pamięć adresową GPU. były odejmowane dwukrotnie przy obliczaniu utraty pamięci RAM. Android 12 wdraża rozwiązanie do obliczania rozmiaru buforów DMA mapowanych do przestrzeni adresowej GPU, co oznacza, że jest on uwzględniany tylko raz w obliczeniach utraconej pamięci RAM.
Szczegóły rozwiązania:
- Interfejs API Memtrack HAL
getMemory()
wywoływany z PID 0 musi przekazywać globalną łączną pamięć prywatną GPU w przypadku MemtrackType::GL i MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - Metoda getMemory() w przypadku wywołania funkcji
PID
0
w przypadku funkcjiMemtrackType
innej niżGL
nie może kończyć się niepowodzeniem. Zamiast tego musi zwracać 0. - Rozwiązanie punktu śledzenia pamięci GPU/eBPF dodane w Androidzie 12 uwzględnia łączną pamięć GPU. Odejmowanie łącznej prywatnej pamięci GPU od łącznej pamięci GPU zapewnia rozmiar DMA-BUF zmapowanych na przestrzeń adresową GPU. Wartość ta może być następnie używana do zwiększania dokładności obliczeń utraconej pamięci RAM przez prawidłowe uwzględnienie wykorzystania pamięci GPU.
- Prywatna pamięć GPU jest uwzględniona w
totalPss
w większości plików HAL Memtrack implementacji, z tego powodu przed usunięciem go zlostRAM
należy usunąć jego duplikaty.
Szczegółowe informacje na temat wdrożonego rozwiązania znajdziesz w następnej sekcji.
Usuwanie zmienności Memtracka z utraconego RAM-u
Implementacje HAL Memtrack mogą się różnić w zależności od partnera, dlatego pamięć GPU uwzględniona w wartości totalPSS
w HAL nie jest zawsze spójna. Aby usunąć zmienność z poziomu lostRAM
, pamięć uwzględniona w parametrach MemtrackType::GRAPHICS
i MemtrackType::GL
jest usuwana z poziomu totalPss
podczas obliczenia lostRAM
.
Pamięć MemtrackType::GRAPHICS
jest usuwana z funkcji totalPss
i zastępowana pamięcią totalExportedDmabuf
w obliczeniach lostRAM
w pliku ActivityManagerService.java, jak pokazano poniżej:
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;
Pamięć (MemtrackType::GL
) została usunięta z: totalPss
i zastąpiona
prywatna pamięć GPU (gpuPrivateUsage
) w obliczeniach lostRAM
w
ActivityManagerService.java
jak poniżej:
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;
Zaktualizowano obliczanie utraconej pamięci RAM
Zarówno łączna prywatna pamięć GPU, jak i łączna wyeksportowana pamięć bufora DMA znajdują się w wartości kernelUsed + totalPss
, która jest usuwana z wartości lostRAM
. Ten
eliminuje zmienność podwójnego liczenia i zmienność w Memtrack z utraty pamięci RAM.
obliczeń.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
Weryfikacja
Testy VTS egzekwują regułę, zgodnie z którą urządzenia uruchamiane na urządzeniach z Androidem 12 z jądrem Linuxa w wersji 5.4 lub nowszej obsługuje getGpuDeviceInfo() API.
Nowy interfejs API Memtrack HAL getGpuDeviceInfo()
musi zwracać informacje o urządzeniu GPU, którego używasz.
Pozwala to lepiej uwzględniać pamięć i obserwację bufora DMA i GPU. wykorzystanie pamięci. Wdróż memtrack HAL AIDL, aby lepiej zmniejszyć ilość pamięci RAM i pamięci księgowości. Ta funkcja nie zależy od usług Google.
Implementacja
Ta funkcja wymaga interfejsu Memtrack HAL AIDL, a instrukcje implementacji w Androidzie 12 są zawarte w kodzie jako komentarze.
W przyszłych wersjach wszystkie interfejsy HIDL HAL zostaną przekształcone w interfejsy AIDL.
Te interfejsy API zostały dodane do 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();
Aby mieć pewność, że wersja działa zgodnie z oczekiwaniami, zintegruj punkty śledzenia w GPU
sterowniki i zaimplementuj interfejs API AIDL memtrack HAL getMemory()
, aby poprawnie zwrócić
globalna łączna ilość prywatnej pamięci GPU wywoływanej z identyfikatorem PID 0 dla MemtrackType::GL
i MemtrackRecord::FLAG_SMAPS_UNACCOUNTED.