Eliminate memtrack variability from the lost RAM calculation

Modify lost RAM calculation to use total mapped dmabuf and private GPU
allocations instead of memtrack HAL's reported Graphics and GL values.
All of memtrack HAL's reported Graphics should be accounted for as part
of mapped dmabufs. In order to not count it twice and not to depend on
memtrack HAL's reported value we exclude it from total PSS calculation
and replace it with mapped dmabufs.
All of memtrack HAL's reported GL should be accounted for as part
of private GPU allocations. In order to not count it twice and not to
depend on memtrack HAL's reported value we exclude it from total PSS
calculation and add GPU private allocations to total kernel memory
usage.

Bug: 165832481
Test: dumpsys meminfo
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: I631488d95cfd91d5428c877b3a004215031dd223
This commit is contained in:
Suren Baghdasaryan
2021-02-10 10:38:03 -08:00
parent f30df7e62e
commit 9785b9a84b
2 changed files with 47 additions and 14 deletions

View File

@@ -1490,7 +1490,9 @@ public class ActivityManagerService extends IActivityManager.Stub
private static final int INDEX_TOTAL_SWAP_PSS = 10; private static final int INDEX_TOTAL_SWAP_PSS = 10;
private static final int INDEX_TOTAL_RSS = 11; private static final int INDEX_TOTAL_RSS = 11;
private static final int INDEX_TOTAL_NATIVE_PSS = 12; private static final int INDEX_TOTAL_NATIVE_PSS = 12;
private static final int INDEX_LAST = 13; private static final int INDEX_TOTAL_MEMTRACK_GRAPHICS = 13;
private static final int INDEX_TOTAL_MEMTRACK_GL = 14;
private static final int INDEX_LAST = 15;
final class UiHandler extends Handler { final class UiHandler extends Handler {
public UiHandler() { public UiHandler() {
@@ -10316,6 +10318,7 @@ public class ActivityManagerService extends IActivityManager.Stub
long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long[] miscRss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; long[] miscRss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
long[] memtrackTmp = new long[4];
long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length]; long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
@@ -10349,6 +10352,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final int reportType; final int reportType;
final long startTime; final long startTime;
final long endTime; final long endTime;
long memtrackGraphics = 0;
long memtrackGl = 0;
if (opts.dumpDetails || (!brief && !opts.oomOnly)) { if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
startTime = SystemClock.currentThreadTimeMillis(); startTime = SystemClock.currentThreadTimeMillis();
@@ -10360,7 +10365,7 @@ public class ActivityManagerService extends IActivityManager.Stub
} else { } else {
reportType = ProcessStats.ADD_PSS_EXTERNAL; reportType = ProcessStats.ADD_PSS_EXTERNAL;
startTime = SystemClock.currentThreadTimeMillis(); startTime = SystemClock.currentThreadTimeMillis();
long pss = Debug.getPss(pid, tmpLong, null); long pss = Debug.getPss(pid, tmpLong, memtrackTmp);
if (pss == 0) { if (pss == 0) {
continue; continue;
} }
@@ -10368,6 +10373,8 @@ public class ActivityManagerService extends IActivityManager.Stub
endTime = SystemClock.currentThreadTimeMillis(); endTime = SystemClock.currentThreadTimeMillis();
mi.dalvikPrivateDirty = (int) tmpLong[0]; mi.dalvikPrivateDirty = (int) tmpLong[0];
mi.dalvikRss = (int) tmpLong[2]; mi.dalvikRss = (int) tmpLong[2];
memtrackGraphics = memtrackTmp[1];
memtrackGl = memtrackTmp[2];
} }
if (!opts.isCheckinRequest && opts.dumpDetails) { if (!opts.isCheckinRequest && opts.dumpDetails) {
pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
@@ -10431,6 +10438,8 @@ public class ActivityManagerService extends IActivityManager.Stub
ss[INDEX_TOTAL_PSS] += myTotalPss; ss[INDEX_TOTAL_PSS] += myTotalPss;
ss[INDEX_TOTAL_SWAP_PSS] += myTotalSwapPss; ss[INDEX_TOTAL_SWAP_PSS] += myTotalSwapPss;
ss[INDEX_TOTAL_RSS] += myTotalRss; ss[INDEX_TOTAL_RSS] += myTotalRss;
ss[INDEX_TOTAL_MEMTRACK_GRAPHICS] += memtrackGraphics;
ss[INDEX_TOTAL_MEMTRACK_GL] += memtrackGl;
MemItem pssItem = new MemItem(r.processName + " (pid " + pid + MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
(hasActivities ? " / activities)" : ")"), r.processName, myTotalPss, (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
myTotalSwapPss, myTotalRss, pid, hasActivities); myTotalSwapPss, myTotalRss, pid, hasActivities);
@@ -10494,6 +10503,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final Debug.MemoryInfo[] memInfos = new Debug.MemoryInfo[1]; final Debug.MemoryInfo[] memInfos = new Debug.MemoryInfo[1];
mAppProfiler.forAllCpuStats((st) -> { mAppProfiler.forAllCpuStats((st) -> {
if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
long memtrackGraphics = 0;
long memtrackGl = 0;
if (memInfos[0] == null) { if (memInfos[0] == null) {
memInfos[0] = new Debug.MemoryInfo(); memInfos[0] = new Debug.MemoryInfo();
} }
@@ -10503,13 +10514,15 @@ public class ActivityManagerService extends IActivityManager.Stub
return; return;
} }
} else { } else {
long pss = Debug.getPss(st.pid, tmpLong, null); long pss = Debug.getPss(st.pid, tmpLong, memtrackTmp);
if (pss == 0) { if (pss == 0) {
return; return;
} }
info.nativePss = (int) pss; info.nativePss = (int) pss;
info.nativePrivateDirty = (int) tmpLong[0]; info.nativePrivateDirty = (int) tmpLong[0];
info.nativeRss = (int) tmpLong[2]; info.nativeRss = (int) tmpLong[2];
memtrackGraphics = memtrackTmp[1];
memtrackGl = memtrackTmp[2];
} }
final long myTotalPss = info.getTotalPss(); final long myTotalPss = info.getTotalPss();
@@ -10519,6 +10532,8 @@ public class ActivityManagerService extends IActivityManager.Stub
ss[INDEX_TOTAL_SWAP_PSS] += myTotalSwapPss; ss[INDEX_TOTAL_SWAP_PSS] += myTotalSwapPss;
ss[INDEX_TOTAL_RSS] += myTotalRss; ss[INDEX_TOTAL_RSS] += myTotalRss;
ss[INDEX_TOTAL_NATIVE_PSS] += myTotalPss; ss[INDEX_TOTAL_NATIVE_PSS] += myTotalPss;
ss[INDEX_TOTAL_MEMTRACK_GRAPHICS] += memtrackGraphics;
ss[INDEX_TOTAL_MEMTRACK_GL] += memtrackGl;
MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
st.name, myTotalPss, info.getSummaryTotalSwapPss(), myTotalRss, st.name, myTotalPss, info.getSummaryTotalSwapPss(), myTotalRss,
@@ -10726,7 +10741,11 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.print(" mapped + "); pw.print(" mapped + ");
pw.print(stringifyKBSize(dmabufUnmapped)); pw.print(stringifyKBSize(dmabufUnmapped));
pw.println(" unmapped)"); pw.println(" unmapped)");
kernelUsed += totalExportedDmabuf; // Account unmapped dmabufs as part of kernel memory allocations
kernelUsed += dmabufUnmapped;
// Replace memtrack HAL reported Graphics category with mapped dmabufs
ss[INDEX_TOTAL_PSS] -= ss[INDEX_TOTAL_MEMTRACK_GRAPHICS];
ss[INDEX_TOTAL_PSS] += dmabufMapped;
} }
final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb(); final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb();
if (totalDmabufHeapPool >= 0) { if (totalDmabufHeapPool >= 0) {
@@ -10746,15 +10765,17 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.print(" dmabuf + "); pw.print(" dmabuf + ");
pw.print(stringifyKBSize(gpuPrivateUsage)); pw.print(stringifyKBSize(gpuPrivateUsage));
pw.println(" private)"); pw.println(" private)");
// Replace memtrack HAL reported GL category with private GPU allocations and
// account it as part of kernel memory allocations
ss[INDEX_TOTAL_PSS] -= ss[INDEX_TOTAL_MEMTRACK_GL];
kernelUsed += gpuPrivateUsage;
} else { } else {
pw.print(" GPU: "); pw.println(stringifyKBSize(gpuUsage)); pw.print(" GPU: "); pw.println(stringifyKBSize(gpuUsage));
} }
} }
/* // Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
* Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of // memInfo.getCachedSizeKb().
* memInfo.getCachedSizeKb().
*/
final long lostRAM = memInfo.getTotalSizeKb() final long lostRAM = memInfo.getTotalSizeKb()
- (ss[INDEX_TOTAL_PSS] - ss[INDEX_TOTAL_SWAP_PSS]) - (ss[INDEX_TOTAL_PSS] - ss[INDEX_TOTAL_SWAP_PSS])
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()

View File

@@ -1322,7 +1322,7 @@ public class AppProfiler {
infoMap.put(mi.pid, mi); infoMap.put(mi.pid, mi);
} }
updateCpuStatsNow(); updateCpuStatsNow();
long[] memtrackTmp = new long[1]; long[] memtrackTmp = new long[4];
long[] swaptrackTmp = new long[2]; long[] swaptrackTmp = new long[2];
// Get a list of Stats that have vsize > 0 // Get a list of Stats that have vsize > 0
final List<ProcessCpuTracker.Stats> stats = getCpuStats(st -> st.vsize > 0); final List<ProcessCpuTracker.Stats> stats = getCpuStats(st -> st.vsize > 0);
@@ -1345,6 +1345,8 @@ public class AppProfiler {
long totalPss = 0; long totalPss = 0;
long totalSwapPss = 0; long totalSwapPss = 0;
long totalMemtrack = 0; long totalMemtrack = 0;
long totalMemtrackGraphics = 0;
long totalMemtrackGl = 0;
for (int i = 0, size = memInfos.size(); i < size; i++) { for (int i = 0, size = memInfos.size(); i < size; i++) {
ProcessMemInfo mi = memInfos.get(i); ProcessMemInfo mi = memInfos.get(i);
if (mi.pss == 0) { if (mi.pss == 0) {
@@ -1355,6 +1357,8 @@ public class AppProfiler {
totalPss += mi.pss; totalPss += mi.pss;
totalSwapPss += mi.swapPss; totalSwapPss += mi.swapPss;
totalMemtrack += mi.memtrack; totalMemtrack += mi.memtrack;
totalMemtrackGraphics += memtrackTmp[1];
totalMemtrackGl += memtrackTmp[2];
} }
Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
@Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
@@ -1521,10 +1525,16 @@ public class AppProfiler {
} else { } else {
final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb(); final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb();
if (totalExportedDmabuf >= 0) { if (totalExportedDmabuf >= 0) {
final long dmabufMapped = Debug.getDmabufMappedSizeKb();
final long dmabufUnmapped = totalExportedDmabuf - dmabufMapped;
memInfoBuilder.append("DMA-BUF: "); memInfoBuilder.append("DMA-BUF: ");
memInfoBuilder.append(stringifyKBSize(totalExportedDmabuf)); memInfoBuilder.append(stringifyKBSize(totalExportedDmabuf));
memInfoBuilder.append("\n"); memInfoBuilder.append("\n");
kernelUsed += totalExportedDmabuf; // Account unmapped dmabufs as part of kernel memory allocations
kernelUsed += dmabufUnmapped;
// Replace memtrack HAL reported Graphics category with mapped dmabufs
totalPss -= totalMemtrackGraphics;
totalPss += dmabufMapped;
} }
final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb(); final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb();
@@ -1547,6 +1557,10 @@ public class AppProfiler {
memInfoBuilder.append(" dmabuf + "); memInfoBuilder.append(" dmabuf + ");
memInfoBuilder.append(stringifyKBSize(gpuPrivateUsage)); memInfoBuilder.append(stringifyKBSize(gpuPrivateUsage));
memInfoBuilder.append(" private)\n"); memInfoBuilder.append(" private)\n");
// Replace memtrack HAL reported GL category with private GPU allocations and
// account it as part of kernel memory allocations
totalPss -= totalMemtrackGl;
kernelUsed += gpuPrivateUsage;
} else { } else {
memInfoBuilder.append(" GPU: "); memInfoBuilder.append(" GPU: ");
memInfoBuilder.append(stringifyKBSize(gpuUsage)); memInfoBuilder.append(stringifyKBSize(gpuUsage));
@@ -1559,10 +1573,8 @@ public class AppProfiler {
totalPss - cachedPss + kernelUsed)); totalPss - cachedPss + kernelUsed));
memInfoBuilder.append("\n"); memInfoBuilder.append("\n");
/* // Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
* Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of // memInfo.getCachedSizeKb().
* memInfo.getCachedSizeKb().
*/
memInfoBuilder.append(" Lost RAM: "); memInfoBuilder.append(" Lost RAM: ");
memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
- (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() - (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()