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

Commit 83b88de7 authored by Ioannis Ilkos's avatar Ioannis Ilkos
Browse files

Add SystemMemory pulled atom in statsd

Initial implementation of kernel-level memory metrics

Bug: 149462065
Bug: 172201884
Test: statsd_testdrive
Change-Id: I9c0e24f2771ce398942845af6934f0cbc64044c0
parent 4aed7225
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1946,7 +1946,13 @@ public final class Debug
     */
    public static final int MEMINFO_KRECLAIMABLE = 15;
    /** @hide */
    public static final int MEMINFO_COUNT = 16;
    public static final int MEMINFO_ACTIVE = 16;
    /** @hide */
    public static final int MEMINFO_INACTIVE = 17;
    /** @hide */
    public static final int MEMINFO_UNEVICTABLE = 18;
    /** @hide */
    public static final int MEMINFO_COUNT = 19;

    /**
     * Retrieves /proc/meminfo.  outSizes is filled with fields
+3 −0
Original line number Diff line number Diff line
@@ -571,6 +571,9 @@ enum {
    MEMINFO_PAGE_TABLES,
    MEMINFO_KERNEL_STACK,
    MEMINFO_KERNEL_RECLAIMABLE,
    MEMINFO_ACTIVE,
    MEMINFO_INACTIVE,
    MEMINFO_UNEVICTABLE,
    MEMINFO_COUNT
};

+27 −0
Original line number Diff line number Diff line
@@ -502,6 +502,8 @@ public class StatsPullAtomService extends SystemService {
                        synchronized (mProcessSystemIonHeapSizeLock) {
                            return pullProcessSystemIonHeapSizeLocked(atomTag, data);
                        }
                    case FrameworkStatsLog.SYSTEM_MEMORY:
                        return pullSystemMemory(atomTag, data);
                    case FrameworkStatsLog.TEMPERATURE:
                        synchronized (mTemperatureLock) {
                            return pullTemperatureLocked(atomTag, data);
@@ -796,6 +798,7 @@ public class StatsPullAtomService extends SystemService {
        registerSystemIonHeapSize();
        registerIonHeapSize();
        registerProcessSystemIonHeapSize();
        registerSystemMemory();
        registerTemperature();
        registerCoolingDevice();
        registerBinderCallsStats();
@@ -1913,6 +1916,30 @@ public class StatsPullAtomService extends SystemService {
        return StatsManager.PULL_SUCCESS;
    }

    private void registerSystemMemory() {
        int tagId = FrameworkStatsLog.SYSTEM_MEMORY;
        mStatsManager.setPullAtomCallback(
                tagId,
                null, // use default PullAtomMetadata values
                DIRECT_EXECUTOR,
                mStatsCallbackImpl
        );
    }

    int pullSystemMemory(int atomTag, List<StatsEvent> pulledData) {
        SystemMemoryUtil.Metrics metrics = SystemMemoryUtil.getMetrics();
        pulledData.add(
                FrameworkStatsLog.buildStatsEvent(
                        atomTag,
                        metrics.unreclaimableSlabKb,
                        metrics.vmallocUsedKb,
                        metrics.pageTablesKb,
                        metrics.kernelStackKb,
                        metrics.totalIonKb,
                        metrics.unaccountedKb));
        return StatsManager.PULL_SUCCESS;
    }

    private void registerTemperature() {
        int tagId = FrameworkStatsLog.TEMPERATURE;
        mStatsManager.setPullAtomCallback(
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.stats.pull;

import android.os.Debug;

/**
 * Snapshots system-wide memory stats and computes unaccounted memory.
 * Thread-safe.
 */
final class SystemMemoryUtil {
    private SystemMemoryUtil() {}

    static Metrics getMetrics() {
        int totalIonKb = (int) Debug.getIonHeapsSizeKb();

        long[] mInfos = new long[Debug.MEMINFO_COUNT];
        Debug.getMemInfo(mInfos);

        long kReclaimableKb = mInfos[Debug.MEMINFO_KRECLAIMABLE];
        // Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE and ION pools.
        // Fall back to using MEMINFO_SLAB_RECLAIMABLE in case of older kernels that do
        // not include KReclaimable meminfo field.
        if (kReclaimableKb == 0) {
            kReclaimableKb = mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE];
        }

        long accountedKb = mInfos[Debug.MEMINFO_FREE]
                + mInfos[Debug.MEMINFO_ZRAM_TOTAL]
                + mInfos[Debug.MEMINFO_BUFFERS]
                + mInfos[Debug.MEMINFO_ACTIVE]
                + mInfos[Debug.MEMINFO_INACTIVE]
                + mInfos[Debug.MEMINFO_UNEVICTABLE]
                + mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE]
                + kReclaimableKb
                + mInfos[Debug.MEMINFO_VM_ALLOC_USED]
                + mInfos[Debug.MEMINFO_PAGE_TABLES]
                + Math.max(totalIonKb, 0);

        if (!Debug.isVmapStack()) {
            // See b/146088882
            accountedKb += mInfos[Debug.MEMINFO_KERNEL_STACK];
        }

        Metrics result = new Metrics();
        result.unreclaimableSlabKb = (int) mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE];
        result.vmallocUsedKb = (int) mInfos[Debug.MEMINFO_VM_ALLOC_USED];
        result.pageTablesKb = (int) mInfos[Debug.MEMINFO_PAGE_TABLES];
        result.kernelStackKb = (int) mInfos[Debug.MEMINFO_KERNEL_STACK];
        result.totalIonKb = totalIonKb;
        result.unaccountedKb = (int) (mInfos[Debug.MEMINFO_TOTAL] - accountedKb);
        return result;
    }

    static final class Metrics {
        public int unreclaimableSlabKb;
        public int vmallocUsedKb;
        public int pageTablesKb;
        public int kernelStackKb;
        public int totalIonKb;
        public int unaccountedKb;
    }
}