1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 21 22 import android.util.Slog; 23 24 import com.android.internal.util.FrameworkStatsLog; 25 26 import java.io.DataInputStream; 27 import java.io.IOException; 28 29 /** 30 * Activity manager communication with lmkd data handling and statsd atom logging 31 */ 32 public final class LmkdStatsReporter { 33 34 static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdStatsReporter" : TAG_AM; 35 36 public static final int KILL_OCCURRED_MSG_SIZE = 80; 37 38 private static final int PRESSURE_AFTER_KILL = 0; 39 private static final int NOT_RESPONDING = 1; 40 private static final int LOW_SWAP_AND_THRASHING = 2; 41 private static final int LOW_MEM_AND_SWAP = 3; 42 private static final int LOW_MEM_AND_THRASHING = 4; 43 private static final int DIRECT_RECL_AND_THRASHING = 5; 44 private static final int LOW_MEM_AND_SWAP_UTIL = 6; 45 private static final int LOW_FILECACHE_AFTER_THRASHING = 7; 46 private static final int LOW_MEM = 8; 47 private static final int DIRECT_RECL_STUCK = 9; 48 49 /** 50 * Processes the LMK_KILL_OCCURRED packet data 51 * Logs the event when LMKD kills a process to reduce memory pressure. 52 * Code: LMK_KILL_OCCURRED = 51 53 */ logKillOccurred(DataInputStream inputData, int totalForegroundServices, int procsWithForegroundServices)54 public static void logKillOccurred(DataInputStream inputData, int totalForegroundServices, 55 int procsWithForegroundServices) { 56 try { 57 final long pgFault = inputData.readLong(); 58 final long pgMajFault = inputData.readLong(); 59 final long rssInBytes = inputData.readLong(); 60 final long cacheInBytes = inputData.readLong(); 61 final long swapInBytes = inputData.readLong(); 62 final long processStartTimeNS = inputData.readLong(); 63 final int uid = inputData.readInt(); 64 final int oomScore = inputData.readInt(); 65 final int minOomScore = inputData.readInt(); 66 final int freeMemKb = inputData.readInt(); 67 final int freeSwapKb = inputData.readInt(); 68 final int killReason = inputData.readInt(); 69 final int thrashing = inputData.readInt(); 70 final int maxThrashing = inputData.readInt(); 71 final String procName = inputData.readUTF(); 72 FrameworkStatsLog.write(FrameworkStatsLog.LMK_KILL_OCCURRED, uid, procName, oomScore, 73 pgFault, pgMajFault, rssInBytes, cacheInBytes, swapInBytes, processStartTimeNS, 74 minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason), thrashing, 75 maxThrashing, totalForegroundServices, procsWithForegroundServices); 76 } catch (IOException e) { 77 Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED"); 78 return; 79 } 80 } 81 mapKillReason(int reason)82 private static int mapKillReason(int reason) { 83 switch (reason) { 84 case PRESSURE_AFTER_KILL: 85 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__PRESSURE_AFTER_KILL; 86 case NOT_RESPONDING: 87 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__NOT_RESPONDING; 88 case LOW_SWAP_AND_THRASHING: 89 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_SWAP_AND_THRASHING; 90 case LOW_MEM_AND_SWAP: 91 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP; 92 case LOW_MEM_AND_THRASHING: 93 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_THRASHING; 94 case DIRECT_RECL_AND_THRASHING: 95 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_AND_THRASHING; 96 case LOW_MEM_AND_SWAP_UTIL: 97 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL; 98 case LOW_FILECACHE_AFTER_THRASHING: 99 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_FILECACHE_AFTER_THRASHING; 100 case LOW_MEM: 101 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM; 102 case DIRECT_RECL_STUCK: 103 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_STUCK; 104 default: 105 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN; 106 } 107 } 108 } 109