• 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     public static final int STATE_CHANGED_MSG_SIZE = 8;
38 
39     private static final int PRESSURE_AFTER_KILL = 0;
40     private static final int NOT_RESPONDING = 1;
41     private static final int LOW_SWAP_AND_THRASHING = 2;
42     private static final int LOW_MEM_AND_SWAP = 3;
43     private static final int LOW_MEM_AND_THRASHING = 4;
44     private static final int DIRECT_RECL_AND_THRASHING = 5;
45     private static final int LOW_MEM_AND_SWAP_UTIL = 6;
46     private static final int LOW_FILECACHE_AFTER_THRASHING = 7;
47 
48     /**
49      * Processes the LMK_KILL_OCCURRED packet data
50      * Logs the event when LMKD kills a process to reduce memory pressure.
51      * Code: LMK_KILL_OCCURRED = 51
52      */
logKillOccurred(DataInputStream inputData)53     public static void logKillOccurred(DataInputStream inputData) {
54         try {
55             final long pgFault = inputData.readLong();
56             final long pgMajFault = inputData.readLong();
57             final long rssInBytes = inputData.readLong();
58             final long cacheInBytes = inputData.readLong();
59             final long swapInBytes = inputData.readLong();
60             final long processStartTimeNS = inputData.readLong();
61             final int uid = inputData.readInt();
62             final int oomScore = inputData.readInt();
63             final int minOomScore = inputData.readInt();
64             final int freeMemKb = inputData.readInt();
65             final int freeSwapKb = inputData.readInt();
66             final int killReason = inputData.readInt();
67             final int thrashing = inputData.readInt();
68             final int maxThrashing = inputData.readInt();
69             final String procName = inputData.readUTF();
70 
71             FrameworkStatsLog.write(FrameworkStatsLog.LMK_KILL_OCCURRED, uid, procName, oomScore,
72                     pgFault, pgMajFault, rssInBytes, cacheInBytes, swapInBytes, processStartTimeNS,
73                     minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason), thrashing,
74                     maxThrashing);
75         } catch (IOException e) {
76             Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
77             return;
78         }
79     }
80 
81     /**
82      * Processes the LMK_STATE_CHANGED packet
83      * Logs the change in LMKD state which is used as start/stop boundaries for logging
84      * LMK_KILL_OCCURRED event.
85      * Code: LMK_STATE_CHANGED = 54
86      */
logStateChanged(int state)87     public static void logStateChanged(int state) {
88         FrameworkStatsLog.write(FrameworkStatsLog.LMK_STATE_CHANGED, state);
89     }
90 
mapKillReason(int reason)91     private static int mapKillReason(int reason) {
92         switch (reason) {
93             case PRESSURE_AFTER_KILL:
94                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__PRESSURE_AFTER_KILL;
95             case NOT_RESPONDING:
96                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__NOT_RESPONDING;
97             case LOW_SWAP_AND_THRASHING:
98                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_SWAP_AND_THRASHING;
99             case LOW_MEM_AND_SWAP:
100                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP;
101             case LOW_MEM_AND_THRASHING:
102                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_THRASHING;
103             case DIRECT_RECL_AND_THRASHING:
104                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__DIRECT_RECL_AND_THRASHING;
105             case LOW_MEM_AND_SWAP_UTIL:
106                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL;
107             case LOW_FILECACHE_AFTER_THRASHING:
108                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_FILECACHE_AFTER_THRASHING;
109             default:
110                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN;
111         }
112     }
113 }
114