• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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