Halaman ini menjelaskan berbagai peningkatan akuntansi memori yang diperkenalkan di Android 12.
Statistik DMA-BUF di sysfs
Di Android 11 dan Android 12, debugfs
tidak dapat
dipasang di build Pengguna. Jadi statistik DMA-BUF telah ditambahkan ke sysfs
di
Direktori /sys/kernel/dmabuf/buffers
di Android 12.
Jalur | Deskripsi |
---|---|
/sys/kernel/dmabuf/buffers
|
Direktori /sys/kernel/dmabuf/buffers berisi snapshot dari
status internal setiap DMA-BUF.
/sys/kernel/dmabuf/buffers/<inode_number> berisi statistik untuk
DMA-BUF dengan nomor {i>
inode<i} unik <inode_number> .
|
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name
|
File hanya baca ini berisi nama pengekspor DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size
|
File hanya baca ini menentukan ukuran DMA-BUF dalam byte. |
libdmabufinfo
API mengurai statistik sysfs
DMA-BUF untuk mengekspos statistik per eksportir dan per buffering.
Perhatikan bahwa driver kernel yang mengekspor DMA-BUF harus menetapkan kolom exp_name
struct dma_buf_export_info
dengan benar ke nama eksportir sebelum
memanggil dma_buf_export()
API untuk membuat DMA-BUF.
Hal ini diperlukan agar libdmabufinfo
dan alat dmabuf_dump
dapat memperoleh statistik per pengekspor yang
kemudian diekspos dalam laporan {i>bug<i}.
Alat dmabuf_dump
telah dimodifikasi untuk menghasilkan informasi ini dengan argumen baru, -b
.
Statistik untuk framework heap DMA-BUF
ION di GKI 2.0 tidak digunakan lagi dan digantikan oleh framework heap DMA-BUF, yang merupakan bagian dari {i>kernel<i} Linux hulu.
Statistik ION global berikut dilacak di Android 11:
- Ukuran total DMA-BUF yang diekspor oleh setiap heap ION
- Ukuran total memori pra-alokasi yang tidak digunakan dan disimpan oleh setiap heap ION
Tidak ada antarmuka yang tersedia untuk mengekspos statistik heap per ION di Android 11.
Tabel berikut membandingkan antarmuka statistik ION dengan untuk perangkat yang menggunakan framework heap DMA-BUF di Android 12.
Android 11 atau Perangkat yang diluncurkan dengan dukungan ION di Android 12 | Peluncuran perangkat dengan heap DMA-BUF di Android 12 | |
---|---|---|
Statistik ION per heap | Tidak ada | Diurai dari statistik sysfs DMA-BUF |
Total ukuran DMA-BUF yang diekspor | /sys/kernel/ion/total_heap_size_kb
(Tidak menyertakan ukuran DMA-BUF yang diekspor oleh pengekspor non-ION) |
Diurai dari statistik sysfs DMA-BUF
(mencakup ukuran semua DMA-BUF yang diekspor). |
Total memori yang digabungkan berdasarkan heap | /sys/kernel/ion/total_pool_size_kb |
/sys/kernel/dma_heap/total_pool_size_kb |
Meningkatkan akurasi penghitungan RAM yang hilang
Sebelumnya, penghitungan RAM yang hilang dilakukan sebagai berikut:
panjang terakhir lostRAM
= memInfo.getTotalSizeKb(
) - (totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
Komponen totalPss
menyertakan penggunaan memori GPU (ditampilkan oleh
antarmuka getMemory()
HAL Memtrack). Komponen kernelUsed
menyertakan total penggunaan memori DMA-BUF.
Namun, untuk perangkat Android, memori GPU berasal dari hal berikut:
- Alokasi langsung yang dilakukan oleh driver GPU menggunakan alokator halaman fisik
- DMA-BUF yang dipetakan ke ruang alamat GPU
Oleh karena itu, DMA-BUF yang dipetakan memori ke dalam ruang alamat GPU dikurangi dua kali ketika RAM yang hilang dihitung. Android 12 menerapkan solusi untuk menghitung ukuran DMA-BUF yang dipetakan ke ruang alamat GPU, yang berarti bahwa DMA-BUF hanya diperhitungkan sekali dalam penghitungan RAM yang Hilang.
Detail solusinya adalah sebagai berikut:
- Memtrack HAL API
getMemory()
saat dipanggil dengan PID 0 harus melaporkan total memori pribadi GPU global, untuk MemtrackType::GL dan MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - getMemory() saat dipanggil dengan
PID
0
untukMemtrackType
selainGL
tidak boleh gagal. Sebaliknya, hasilnya harus menampilkan 0. - Solusi tracepoint/eBPF memori GPU yang ditambahkan di Android 12 untuk total memori GPU. Mengurangi total memori pribadi GPU dari total memori GPU akan memberikan DMA-BUF yang dipetakan ke dalam ruang alamat GPU. Nilai tersebut kemudian dapat digunakan untuk meningkatkan akurasi penghitungan RAM yang Hilang dengan memperhitungkan penggunaan memori GPU.
- Memori GPU pribadi disertakan dalam
totalPss
di sebagian besar Memtrack HAL implementasi dan, oleh karena itu, duplikatnya harus dihapus sebelum menghapusnya darilostRAM
.
Solusi yang diimplementasikan dijelaskan di bagian berikutnya.
Menghapus variabilitas Memtrack dari RAM yang hilang
Karena implementasi HAL Memtrack dapat bervariasi di seluruh partner, memori GPU
yang disertakan dalam totalPSS
dari HAL tidak selalu konsisten. Untuk menghapus
variabilitas dari lostRAM
, memori yang diperhitungkan dalam MemtrackType::GRAPHICS
dan MemtrackType::GL
dihapus dari totalPss
selama penghitungan lostRAM
.
Memori MemtrackType::GRAPHICS
dihapus dari totalPss
dan diganti dengan
memori totalExportedDmabuf
dalam penghitungan lostRAM
di
ActivityManagerService.java
seperti yang ditunjukkan di bawah:
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;
Memori MemtrackType::GL
dihapus dari totalPss
dan diganti dengan
memori GPU pribadi (gpuPrivateUsage
) dalam penghitungan lostRAM
di
ActivityManagerService.java
sebagaimana ditunjukkan di bawah ini:
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;
Penghitungan RAM yang hilang diperbarui
Total memori GPU pribadi dan total memori buffer DMA yang diekspor
terdapat dalam kernelUsed + totalPss
yang akan dihapus dari lostRAM
. Hal ini
menghilangkan penghitungan ganda dan variabilitas Memtrack dari penghitungan
RAM yang hilang.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
Validasi
Pengujian VTS menerapkan aturan yang diluncurkan perangkat di Android 12 dengan kernel Linux versi 5.4 atau yang lebih tinggi mendukung getGpuDeviceInfo() Compute Engine API.
Memtrack HAL API getGpuDeviceInfo()
baru harus menampilkan informasi tentang perangkat GPU yang digunakan.
Hal ini memberikan penghitungan dan visibilitas memori yang lebih baik ke buffer DMA dan GPU penggunaan memori. Mengimplementasikan memtrack AIDL HAL untuk kehilangan RAM dan memori yang lebih baik pencatatan. Fitur ini tidak bergantung pada layanan Google.
Implementasi
Fitur ini bergantung pada AIDL Memtrack HAL, dan petunjuk untuk menerapkannya di Android 12 disertakan dalam kode sebagai komentar.
Semua HAL HIDL direncanakan akan dikonversi menjadi AIDL dalam rilis mendatang.
API berikut telah ditambahkan ke 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();
Untuk memastikan versi Anda berfungsi sebagaimana mestinya, integrasikan tracepoint di GPU Anda
driver, dan menerapkan AIDL memtrack HAL getMemory()
API untuk menampilkan
total memori pribadi GPU global saat dipanggil dengan PID 0 untuk MemtrackType::GL
dan MemtrackRecord::FLAG_SMAPS_UNACCOUNTED.