На этой странице описаны различные улучшения учета памяти, представленные в Android 12.
Статистика DMA-BUF в sysfs
В Android 11 и Android 12 debugfs
нельзя монтировать в пользовательские сборки. Таким образом, статистика DMA-BUF была добавлена в sysfs
в каталоге /sys/kernel/dmabuf/buffers
в Android 12.
Путь | Описание |
---|---|
/sys/kernel/dmabuf/buffers | Каталог /sys/kernel/dmabuf/buffers содержит снимок внутреннего состояния каждого DMA-BUF. /sys/kernel/dmabuf/buffers/<inode_number> содержит статистику для DMA-BUF с уникальным номером индексного дескриптора <inode_number> . |
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name | Этот файл, доступный только для чтения, содержит имя экспортера DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size | Этот файл, доступный только для чтения, определяет размер DMA-BUF в байтах. |
API libdmabufinfo
анализирует статистику sysfs
DMA-BUF, чтобы предоставить статистику для каждого экспортера и каждого буфера.
Обратите внимание, что драйверы ядра, которые экспортируют DMA-BUF, должны правильно установить в поле exp_name
struct dma_buf_export_info
имя экспортера, прежде чем вызывать API dma_buf_export()
для создания DMA-BUF. Это необходимо для того, чтобы libdmabufinfo
и инструмент dmabuf_dump
получали статистику по каждому экспортеру, которая затем отображается в отчете об ошибке.
Инструмент dmabuf_dump был изменен для вывода этой информации с новым аргументом -b
.
Статистика для структуры куч DMA-BUF
ION в GKI 2.0 устарел в пользу фреймворка кучи DMA-BUF , который является частью исходного ядра Linux.
В Android 11 отслеживается следующая глобальная статистика ION:
- Общий размер DMA-BUF, экспортируемых каждой кучей ION
- Общий размер неиспользуемой предварительно выделенной памяти, хранящейся в каждой куче ION.
В Android 11 нет интерфейса для предоставления статистики кучи по каждому ION.
В следующей таблице сравниваются интерфейсы статистики ION с их аналогами для устройств, использующих структуру кучи DMA-BUF в Android 12.
Android 11 или устройства, запускаемые с поддержкой ION в Android 12 | Устройства, запускающиеся с кучей DMA-BUF в Android 12 | |
---|---|---|
Статистика ION по куче | Никто | Анализируется из статистики sysfs DMA-BUF. |
Общий размер экспортированных DMA-BUF | /sys/kernel/ion/total_heap_size_kb (Не включает размер DMA-BUF, экспортируемых экспортерами, не относящимися к ION) | Анализируется из статистики sysfs DMA-BUF. (включая размер всех экспортированных DMA-BUF). |
Общая память, объединенная в кучу | /sys/kernel/ion/total_pool_size_kb | /sys/kernel/dma_heap/total_pool_size_kb |
Улучшите точность расчета потерянной оперативной памяти.
Ранее расчет потерянной оперативной памяти выполнялся следующим образом:
Final long lostRAM
= memInfo.getTotalSizeKb(
) - ( totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
Компонент totalPss
включал данные об использовании памяти графического процессора (возвращаемые интерфейсом getMemory() Memtrack HAL). Компонент kernelUsed
учитывал общее использование памяти DMA-BUF. Однако для устройств Android память графического процессора была следующей:
- Прямое выделение, выполняемое драйвером графического процессора с использованием физического распределителя страниц.
- DMA-BUF, сопоставленные с адресным пространством графического процессора.
Таким образом, DMA-BUF, которые были отображены в адресное пространство графического процессора, вычитались дважды при подсчете потерянной оперативной памяти. В Android 12 реализовано решение для расчета размера DMA-BUF, сопоставленного с адресным пространством графического процессора, что означает, что он учитывается только один раз при расчете потерянной оперативной памяти.
Подробности решения следующие:
- API-интерфейс Memtrack HAL
getMemory()
при вызове с PID 0 должен сообщать общий общий объем частной памяти графического процессора для MemtrackType::GL и MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - getMemory() при вызове с
PID
0
дляMemtrackType
отличного отGL
не должен давать сбой. Вместо этого он должен вернуть 0. - Решение трассировки памяти графического процессора/eBPF , добавленное в Android 12, учитывает общий объем памяти графического процессора. Вычитание общего объема частной памяти графического процессора из общего объема памяти графического процессора дает размер DMA-BUF, сопоставленных с адресным пространством графического процессора. Затем это значение можно использовать для повышения точности вычислений потери оперативной памяти за счет правильного учета использования памяти графического процессора.
- Частная память графического процессора включена в
totalPss
в большинстве реализаций Memtrack HAL и поэтому должна быть дедуплицирована перед ее удалением изlostRAM
.
Реализованное решение подробно описано в следующем разделе.
Удалить изменчивость Memtrack из потерянной оперативной памяти
Поскольку реализации Memtrack HAL могут различаться у разных партнеров, память графического процессора, включенная в totalPSS
из HAL, не всегда согласована. Чтобы удалить изменчивость из lostRAM
, память, учтенная в MemtrackType::GRAPHICS
и MemtrackType::GL
, удаляется из totalPss
во время расчета lostRAM
.
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
и заменяется частной памятью графического процессора ( 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;
Обновлен расчет потерянной оперативной памяти.
Как общий объем частной памяти графического процессора, так и общий объем экспортированной буферной памяти DMA содержатся в kernelUsed + totalPss
, который удален из lostRAM
. Это исключает как двойной учет, так и изменчивость Memtrack при расчете потерянной оперативной памяти.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
Валидация
Тесты VTS обеспечивают соблюдение правила, согласно которому устройства, запускаемые в Android 12 с ядром Linux версии 5.4 или выше, поддерживают API getGpuDeviceInfo() .
Новый Memtrack HAL API getGpuDeviceInfo()
должен возвращать информацию об используемом устройстве графического процессора.
Это обеспечивает лучший учет памяти и видимость использования буфера DMA и памяти графического процессора. Внедрите memtrack AIDL HAL для лучшего учета потерянной оперативной памяти и памяти. Эта функция не зависит от сервисов Google.
Выполнение
Эта функция зависит от AIDL Memtrack HAL , а инструкции по ее реализации в Android 12 включены в код в виде комментариев.
В будущих выпусках все HIDL HAL планируется преобразовать в AIDL.
Следующие API были добавлены в 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();
Чтобы ваша версия работала должным образом, интегрируйте точки трассировки в драйверы графического процессора и реализуйте API AIDL memtrack HAL getMemory()
чтобы правильно возвращать глобальную общую частную память графического процессора при вызове с PID 0 для MemtrackType::GL и MemtrackRecord:: FLAG_SMAPS_UNACCOUNTED.
На этой странице описаны различные улучшения учета памяти, представленные в Android 12.
Статистика DMA-BUF в sysfs
В Android 11 и Android 12 debugfs
нельзя монтировать в пользовательские сборки. Таким образом, статистика DMA-BUF была добавлена в sysfs
в каталоге /sys/kernel/dmabuf/buffers
в Android 12.
Путь | Описание |
---|---|
/sys/kernel/dmabuf/buffers | Каталог /sys/kernel/dmabuf/buffers содержит снимок внутреннего состояния каждого DMA-BUF. /sys/kernel/dmabuf/buffers/<inode_number> содержит статистику для DMA-BUF с уникальным номером индексного дескриптора <inode_number> . |
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name | Этот файл, доступный только для чтения, содержит имя экспортера DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size | Этот файл, доступный только для чтения, определяет размер DMA-BUF в байтах. |
API libdmabufinfo
анализирует статистику sysfs
DMA-BUF, чтобы предоставить статистику для каждого экспортера и каждого буфера.
Обратите внимание, что драйверы ядра, которые экспортируют DMA-BUF, должны правильно установить в поле exp_name
struct dma_buf_export_info
имя экспортера, прежде чем вызывать API dma_buf_export()
для создания DMA-BUF. Это необходимо для того, чтобы libdmabufinfo
и инструмент dmabuf_dump
получали статистику по каждому экспортеру, которая затем отображается в отчете об ошибке.
Инструмент dmabuf_dump был изменен для вывода этой информации с новым аргументом -b
.
Статистика для структуры куч DMA-BUF
ION в GKI 2.0 устарел в пользу фреймворка кучи DMA-BUF , который является частью исходного ядра Linux.
В Android 11 отслеживается следующая глобальная статистика ION:
- Общий размер DMA-BUF, экспортируемых каждой кучей ION
- Общий размер неиспользуемой предварительно выделенной памяти, хранящейся в каждой куче ION
В Android 11 нет интерфейса для предоставления статистики кучи по каждому ION.
В следующей таблице сравниваются интерфейсы статистики ION с их аналогами для устройств, использующих структуру кучи DMA-BUF в Android 12.
Android 11 или устройства, запускаемые с поддержкой ION в Android 12 | Устройства, запускающиеся с кучей DMA-BUF в Android 12 | |
---|---|---|
Статистика ION по куче | Никто | Анализируется из статистики sysfs DMA-BUF. |
Общий размер экспортированных DMA-BUF | /sys/kernel/ion/total_heap_size_kb (Не включает размер DMA-BUF, экспортируемых экспортерами, не относящимися к ION) | Анализируется на основе статистики sysfs DMA-BUF. (включает размер всех экспортированных DMA-BUF). |
Общая память, объединенная в кучу | /sys/kernel/ion/total_pool_size_kb | /sys/kernel/dma_heap/total_pool_size_kb |
Улучшите точность расчета потерянной оперативной памяти.
Ранее расчет потерянной оперативной памяти выполнялся следующим образом:
Final long lostRAM
= memInfo.getTotalSizeKb(
) - ( totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
Компонент totalPss
включал данные об использовании памяти графического процессора (возвращаемые интерфейсом getMemory() Memtrack HAL). Компонент kernelUsed
учитывал общее использование памяти DMA-BUF. Однако для устройств Android память графического процессора была следующей:
- Прямое выделение, выполняемое драйвером графического процессора с использованием физического распределителя страниц.
- DMA-BUF, сопоставленные с адресным пространством графического процессора.
Таким образом, DMA-BUF, которые были отображены в адресном пространстве графического процессора, вычитались дважды при подсчете потерянной оперативной памяти. В Android 12 реализовано решение для расчета размера DMA-BUF, сопоставленного с адресным пространством графического процессора, что означает, что он учитывается только один раз при расчете потерянной оперативной памяти.
Подробности решения следующие:
- API-интерфейс Memtrack HAL
getMemory()
при вызове с PID 0 должен сообщать общий общий объем частной памяти графического процессора для MemtrackType::GL и MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - getMemory() при вызове с
PID
0
дляMemtrackType
отличного отGL
не должен давать сбой. Вместо этого он должен вернуть 0. - Решение трассировки памяти графического процессора/eBPF , добавленное в Android 12, учитывает общий объем памяти графического процессора. Вычитание общего объема частной памяти графического процессора из общего объема памяти графического процессора дает размер DMA-BUF, сопоставленных с адресным пространством графического процессора. Затем это значение можно использовать для повышения точности вычислений потери оперативной памяти за счет правильного учета использования памяти графического процессора.
- Частная память графического процессора включена в
totalPss
в большинстве реализаций Memtrack HAL и поэтому должна быть дедуплицирована перед ее удалением изlostRAM
.
Реализованное решение подробно описано в следующем разделе.
Удалить изменчивость Memtrack из потерянной оперативной памяти
Поскольку реализации Memtrack HAL могут различаться у разных партнеров, память графического процессора, включенная в totalPSS
из HAL, не всегда согласована. Чтобы удалить изменчивость из lostRAM
, память, учтенная в MemtrackType::GRAPHICS
и MemtrackType::GL
, удаляется из totalPss
во время расчета lostRAM
.
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
и заменяется частной памятью графического процессора ( 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;
Обновлен расчет потерянной оперативной памяти.
Как общий объем частной памяти графического процессора, так и общий объем экспортированной буферной памяти DMA содержатся в kernelUsed + totalPss
, который удален из lostRAM
. Это исключает как двойной учет, так и изменчивость Memtrack при расчете потерянной оперативной памяти.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
Валидация
Тесты VTS обеспечивают соблюдение правила, согласно которому устройства, запускаемые в Android 12 с ядром Linux версии 5.4 или выше, поддерживают API getGpuDeviceInfo() .
Новый Memtrack HAL API getGpuDeviceInfo()
должен возвращать информацию об используемом устройстве графического процессора.
Это обеспечивает лучший учет памяти и видимость использования буфера DMA и памяти графического процессора. Внедрите memtrack AIDL HAL для лучшего учета потерянной оперативной памяти и памяти. Эта функция не зависит от сервисов Google.
Выполнение
Эта функция зависит от AIDL Memtrack HAL , а инструкции по ее реализации в Android 12 включены в код в виде комментариев.
В будущих выпусках все HIDL HAL планируется преобразовать в AIDL.
Следующие API были добавлены в 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();
Чтобы ваша версия работала должным образом, интегрируйте точки трассировки в драйверы графического процессора и реализуйте API AIDL memtrack HAL getMemory()
чтобы правильно возвращать глобальную общую частную память графического процессора при вызове с PID 0 для MemtrackType::GL и MemtrackRecord:: FLAG_SMAPS_UNACCOUNTED.