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

Commit 3bea895a authored by Rafal Slawik's avatar Rafal Slawik
Browse files

Add ProcessMemoryHighWaterMark atom

Collection of the RSS high-water mark is moved to a separate atom to
improve performance, increase flexibility and overcome security
constrainsts.
Performance: avoid reading /proc/pid/status in ProcessMemoryState;
flexibility: allow pulling RSS high-water mark on a different schedule;
security: add single point where we can trigger the high-water mark
reset.
The RSS high-water mark will be removed from ProcessMemoryState and
NativeProcessMemoryState atoms in a followup-up CL to ensure that the
collected data is continuous.

Bug: 119598534
Test: atest UidAtomTests#testProcessMemoryHighWaterMark
Change-Id: I52da7b5e695f771f1551e1f6a6a773bded4504d1
parent 7e0404f1
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ message Atom {
    }

    // Pulled events will start at field 10000.
    // Next: 10038
    // Next: 10043
    oneof pulled {
        WifiBytesTransfer wifi_bytes_transfer = 10000;
        WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -203,6 +203,7 @@ message Atom {
        DeviceCalculatedPowerUse device_calculated_power_use = 10039;
        DeviceCalculatedPowerBlameUid device_calculated_power_blame_uid = 10040;
        DeviceCalculatedPowerBlameOther device_calculated_power_blame_other = 10041;
        ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042;
    }

    // DO NOT USE field numbers above 100,000 in AOSP.
@@ -2529,7 +2530,8 @@ message ProcessMemoryState {
    // RSS high watermark.
    // Peak RSS usage of the process. Value is read from the VmHWM field in /proc/PID/status or
    // from memory.max_usage_in_bytes under /dev/memcg if the device uses per-app memory cgroups.
    optional int64 rss_high_watermark_in_bytes = 9;
    // Deprecated: use ProcessMemoryHighWaterMark atom instead.
    optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true];

    // Elapsed real time when the process started.
    // Value is read from /proc/PID/stat, field 22. 0 if read from per-app memory cgroups.
@@ -2557,13 +2559,30 @@ message NativeProcessMemoryState {

    // RSS high watermark.
    // Peak RSS usage of the process. Value is read from the VmHWM field in /proc/PID/status.
    optional int64 rss_high_watermark_in_bytes = 6;
    // Deprecated: use ProcessMemoryHighWaterMark atom instead.
    optional int64 rss_high_watermark_in_bytes = 6 [deprecated = true];

    // Elapsed real time when the process started.
    // Value is read from /proc/PID/stat, field 22.
    optional int64 start_time_nanos = 7;
}

/*
 * Logs the memory high-water mark for a process.
 * Recorded in ActivityManagerService.
 */
message ProcessMemoryHighWaterMark {
    // The uid if available. -1 means not available.
    optional int32 uid = 1 [(is_uid) = true];

    // The process name. Provided by ActivityManagerService or read from /proc/PID/cmdline.
    optional string process_name = 2;

    // RSS high-water mark. Peak RSS usage of the process. Read from the VmHWM field in
    // /proc/PID/status.
    optional int64 rss_high_water_mark_in_bytes = 3;
}

/*
 * Elapsed real time from SystemClock.
 */
+5 −0
Original line number Diff line number Diff line
@@ -180,6 +180,11 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
          {2, 7},
          1 * NS_PER_SEC,
          new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}},
        {android::util::PROCESS_MEMORY_HIGH_WATER_MARK,
         {{3},
          {2},
          1 * NS_PER_SEC,
          new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}},
        // temperature
        {android::util::TEMPERATURE, {{}, {}, 1 * NS_PER_SEC, new ResourceThermalManagerPuller()}},
        // binder_calls
+7 −0
Original line number Diff line number Diff line
@@ -160,6 +160,13 @@ public abstract class ActivityManagerInternal {
     */
    public abstract List<ProcessMemoryState> getMemoryStateForProcesses();

    /**
     * Returns a list that contains the memory high-water mark for currently running processes.
     *
     * Only processes managed by ActivityManagerService are included.
     */
    public abstract List<ProcessMemoryHighWaterMark> getMemoryHighWaterMarkForProcesses();

    /**
     * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
     * needed.
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.app;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * The memory high-water mark value for a process.
 * {@hide}
 */
public final class ProcessMemoryHighWaterMark implements Parcelable {
    public final int uid;
    public final String processName;
    public final long rssHighWaterMarkInBytes;

    public ProcessMemoryHighWaterMark(int uid, String processName, long rssHighWaterMarkInBytes) {
        this.uid = uid;
        this.processName = processName;
        this.rssHighWaterMarkInBytes = rssHighWaterMarkInBytes;
    }

    private ProcessMemoryHighWaterMark(Parcel in) {
        uid = in.readInt();
        processName = in.readString();
        rssHighWaterMarkInBytes = in.readLong();
    }

    public static final Creator<ProcessMemoryHighWaterMark> CREATOR =
            new Creator<ProcessMemoryHighWaterMark>() {
                @Override
                public ProcessMemoryHighWaterMark createFromParcel(Parcel in) {
                    return new ProcessMemoryHighWaterMark(in);
                }

                @Override
                public ProcessMemoryHighWaterMark[] newArray(int size) {
                    return new ProcessMemoryHighWaterMark[size];
                }
            };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(uid);
        parcel.writeString(processName);
        parcel.writeLong(rssHighWaterMarkInBytes);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ public final class ProcessMemoryState implements Parcelable {
    public final long rssInBytes;
    public final long cacheInBytes;
    public final long swapInBytes;
    // TODO(rslawik): Delete this field once ProcessMemoryHighWaterMark is ready.
    public final long rssHighWatermarkInBytes;
    public final long startTimeNanos;

Loading