Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58106423 authored by Alessio Balsini's avatar Alessio Balsini Committed by Android (Google) Code Review
Browse files

Merge "Parser for DMA buffer memory allocations in procfs" into main

parents d9a51971 c7060f86
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -15,7 +15,9 @@
 */
package com.android.internal.os;

import static android.os.Process.*;
import static android.os.Process.PROC_NEWLINE_TERM;
import static android.os.Process.PROC_OUT_LONG;
import static android.os.Process.PROC_OUT_STRING;

import android.annotation.Nullable;
import android.os.Process;
@@ -35,6 +37,13 @@ public final class ProcfsMemoryUtil {
    private static final String[] VMSTAT_KEYS = new String[] {
            "oom_kill"
    };
    private static final int[] DMABUF_FILE_FORMAT = new int[] {PROC_OUT_LONG};

    public enum DmaBufType {
        RSS,
        RSS_HWM,
        PSS
    };

    private ProcfsMemoryUtil() {}

@@ -81,6 +90,47 @@ public final class ProcfsMemoryUtil {
        return snapshot;
    }

    /**
     * Reads dmabuf stats of the current process from procfs.
     *
     * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/pid/{dmabuf_rss,
     * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available.
     */
    public static int readDmabufFromProcfs(DmaBufType type, int pid) {
        return readDmabufFromProcfs(type, String.valueOf(pid));
    }

    /**
     * Reads dmabuf stats of the current process from procfs.
     *
     * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/self/{dmabuf_rss,
     * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available.
     */
    public static int readDmabufFromProcfs(DmaBufType type) {
        return readDmabufFromProcfs(type, "self");
    }

    private static int readDmabufFromProcfs(DmaBufType type, String path) {
        // These files have maximum 1 line.
        long[] output = new long[1];
        String dmabuf_file = switch (type) {
            case RSS -> "dmabuf_rss";
            case RSS_HWM -> "dmabuf_rss_hwm";
            case PSS -> "dmabuf_pss";
        };

        if (!Process.readProcFile(
                "/proc/" + path + "/" + dmabuf_file, DMABUF_FILE_FORMAT, null, output, null)) {
            /* Catches the case when the file is empty, doesn't exist, or the
             * kernel does not support reporting these values. We should not
             * report the value 0, as it would correspond to no dmabuf memory
             * allocations, so we report an error value of -1. */
            return -1;
        }

        return (int) (output[0] / 1024);
    }

    /**
     * Reads cmdline of a process from procfs.
     *
+62 −27
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@ import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
import static android.util.MathUtils.constrain;
import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID;

import static com.android.internal.os.ProcfsMemoryUtil.DmaBufType;
import static com.android.internal.os.ProcfsMemoryUtil.getProcessCmdlines;
import static com.android.internal.os.ProcfsMemoryUtil.readCmdlineFromProcfs;
import static com.android.internal.os.ProcfsMemoryUtil.readDmabufFromProcfs;
import static com.android.internal.os.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_STATS__GESTURE_SHORTCUT_TYPE__TRIPLE_TAP;
@@ -2549,11 +2551,17 @@ public class StatsPullAtomService extends SystemService {
            if (snapshot == null) {
                continue;
            }
            pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid,
            final int dmaBufRssHighWaterMarkInKilobytes =
                    readDmabufFromProcfs(DmaBufType.RSS_HWM, managedProcess.pid);
            pulledData.add(
                    FrameworkStatsLog.buildStatsEvent(
                            atomTag,
                            managedProcess.uid,
                            managedProcess.processName,
                            // RSS high-water mark in bytes.
                            snapshot.rssHighWaterMarkInKilobytes * 1024L,
                    snapshot.rssHighWaterMarkInKilobytes));
                            snapshot.rssHighWaterMarkInKilobytes,
                            dmaBufRssHighWaterMarkInKilobytes));
        }
        // Complement the data with native system processes
        SparseArray<String> processCmdlines = getProcessCmdlines();
@@ -2564,11 +2572,17 @@ public class StatsPullAtomService extends SystemService {
            if (snapshot == null) {
                continue;
            }
            pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid,
            final int dmaBufRssHighWaterMarkInKilobytes =
                    readDmabufFromProcfs(DmaBufType.RSS_HWM, processCmdlines.keyAt(i));
            pulledData.add(
                    FrameworkStatsLog.buildStatsEvent(
                            atomTag,
                            snapshot.uid,
                            processCmdlines.valueAt(i),
                            // RSS high-water mark in bytes.
                            snapshot.rssHighWaterMarkInKilobytes * 1024L,
                    snapshot.rssHighWaterMarkInKilobytes));
                            snapshot.rssHighWaterMarkInKilobytes,
                            dmaBufRssHighWaterMarkInKilobytes));
        }
        // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
        SystemProperties.set("sys.rss_hwm_reset.on", "1");
@@ -2600,13 +2614,25 @@ public class StatsPullAtomService extends SystemService {
            if (snapshot == null) {
                continue;
            }
            pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid,
                    managedProcess.processName, managedProcess.pid, managedProcess.oomScore,
                    snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes,
            final int dmaBufRssInKilobytes =
                    readDmabufFromProcfs(DmaBufType.RSS, managedProcess.pid);
            pulledData.add(
                    FrameworkStatsLog.buildStatsEvent(
                            atomTag,
                            managedProcess.uid,
                            managedProcess.processName,
                            managedProcess.pid,
                            managedProcess.oomScore,
                            snapshot.rssInKilobytes,
                            snapshot.anonRssInKilobytes,
                            snapshot.swapInKilobytes,
                            snapshot.anonRssInKilobytes + snapshot.swapInKilobytes,
                    gpuMemPerPid.get(managedProcess.pid), managedProcess.hasForegroundServices,
                    snapshot.rssShmemKilobytes, managedProcess.mHostingComponentTypes,
                    managedProcess.mHistoricalHostingComponentTypes));
                            gpuMemPerPid.get(managedProcess.pid),
                            managedProcess.hasForegroundServices,
                            snapshot.rssShmemKilobytes,
                            managedProcess.mHostingComponentTypes,
                            managedProcess.mHistoricalHostingComponentTypes,
                            dmaBufRssInKilobytes));
        }
        // Complement the data with native system processes. Given these measurements can be taken
        // in response to LMKs happening, we want to first collect the managed app stats (to
@@ -2620,16 +2646,25 @@ public class StatsPullAtomService extends SystemService {
            if (snapshot == null) {
                continue;
            }
            pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid,
                    processCmdlines.valueAt(i), pid,
            final int dmaBufRssInKilobytes = readDmabufFromProcfs(DmaBufType.RSS, pid);
            pulledData.add(
                    FrameworkStatsLog.buildStatsEvent(
                            atomTag,
                            snapshot.uid,
                            processCmdlines.valueAt(i),
                            pid,
                            -1001 /*Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.*/,
                    snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes,
                            snapshot.rssInKilobytes,
                            snapshot.anonRssInKilobytes,
                            snapshot.swapInKilobytes,
                            snapshot.anonRssInKilobytes + snapshot.swapInKilobytes,
                    gpuMemPerPid.get(pid), false /* has_foreground_services */,
                            gpuMemPerPid.get(pid),
                            false /* has_foreground_services */,
                            snapshot.rssShmemKilobytes,
                            // Native processes don't really have a hosting component type.
                            HOSTING_COMPONENT_TYPE_EMPTY,
                    HOSTING_COMPONENT_TYPE_EMPTY));
                            HOSTING_COMPONENT_TYPE_EMPTY,
                            dmaBufRssInKilobytes));
        }
        return StatsManager.PULL_SUCCESS;
    }