• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2018 Google, Inc
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 #ifndef _STATSLOG_H_
18 #define _STATSLOG_H_
19 
20 #include <lmkd.h>
21 
22 #include <assert.h>
23 #include <inttypes.h>
24 #include <stdbool.h>
25 #include <sys/cdefs.h>
26 #include <sys/types.h>
27 
28 #include <cutils/properties.h>
29 #include <memevents/memevents.h>
30 
31 __BEGIN_DECLS
32 
33 #define MAX_TASKNAME_LEN 128
34 
35 /*
36  * Max LMKD reply packet length in bytes
37  * Notes about size calculation:
38  * 4 bytes for packet type
39  * 88 bytes for the LmkKillOccurred fields: memory_stat + kill_stat
40  * 2 bytes for process name string size
41  * MAX_TASKNAME_LEN bytes for the process name string
42  *
43  * Must be in sync with LmkdConnection.java
44  */
45 #define LMKD_REPLY_MAX_SIZE 222
46 
47 /* LMK_MEMORY_STATS packet payload */
48 struct memory_stat {
49     int64_t pgfault;
50     int64_t pgmajfault;
51     int64_t rss_in_bytes;
52     int64_t cache_in_bytes;
53     int64_t swap_in_bytes;
54     int64_t process_start_time_ns;
55 };
56 
57 // If you update this, also update the corresponding stats enum mapping and LmkdStatsReporter.java
58 enum kill_reasons {
59     NONE = -1, /* To denote no kill condition */
60     PRESSURE_AFTER_KILL = 0,
61     NOT_RESPONDING,
62     LOW_SWAP_AND_THRASHING,
63     LOW_MEM_AND_SWAP,
64     LOW_MEM_AND_THRASHING,
65     DIRECT_RECL_AND_THRASHING,
66     LOW_MEM_AND_SWAP_UTIL,
67     LOW_FILECACHE_AFTER_THRASHING,
68     LOW_MEM,
69     DIRECT_RECL_STUCK,
70     /* reserve aosp kill 0 ~ 999 */
71     VENDOR_KILL_REASON_BASE = 1000,
72     VENDOR_KILL_REASON_END = VENDOR_KILL_REASON_BASE + NUM_VENDOR_LMK_KILL_REASON - 1,
73     KILL_REASON_COUNT
74 };
75 
76 /* LMK_KILL_STAT packet payload */
77 struct kill_stat {
78     int32_t uid;
79     const char *taskname;
80     enum kill_reasons kill_reason;
81     int32_t oom_score;
82     int32_t min_oom_score;
83     int64_t free_mem_kb;
84     int64_t free_swap_kb;
85     int32_t thrashing;
86     int32_t max_thrashing;
87 };
88 
89 /* LMKD reply packet to hold data for the LmkKillOccurred statsd atom */
90 typedef char LMK_KILL_OCCURRED_PACKET[LMKD_REPLY_MAX_SIZE];
91 
92 #ifdef LMKD_LOG_STATS
93 
94 #define PROC_STAT_FILE_PATH "/proc/%d/stat"
95 #define PROC_STAT_BUFFER_SIZE 1024
96 #define BYTES_IN_KILOBYTE 1024
97 
98 /**
99  * Produces packet with the event when LMKD kills a process to reduce memory pressure.
100  * Code: LMK_KILL_OCCURRED = 51
101  */
102 size_t lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet,
103                                    struct kill_stat *kill_st,
104                                    struct memory_stat *mem_st);
105 
106 /**
107  * Reads memory stats used to log the statsd atom. Returns non-null ptr on success.
108  */
109 struct memory_stat *stats_read_memory_stat(bool per_app_memcg, int pid, uid_t uid,
110                                            int64_t rss_bytes, int64_t swap_bytes);
111 
112 /**
113  * Registers a process taskname by pid, while it is still alive.
114  */
115 void stats_store_taskname(int pid, const char* taskname);
116 
117 /**
118  * Unregister all process tasknames.
119  */
120 void stats_purge_tasknames();
121 
122 /**
123  * Unregister a process taskname, e.g. after it has been killed.
124  */
125 void stats_remove_taskname(int pid);
126 
127 const char* stats_get_task_name(int pid);
128 
129 #else /* LMKD_LOG_STATS */
130 
131 static inline size_t
lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet __unused,struct kill_stat * kill_st __unused,struct memory_stat * mem_st __unused)132 lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet __unused,
133                             struct kill_stat *kill_st __unused,
134                             struct memory_stat *mem_st __unused) {
135     return -EINVAL;
136 }
137 
stats_read_memory_stat(bool per_app_memcg __unused,int pid __unused,uid_t uid __unused,int64_t rss_bytes __unused,int64_t swap_bytes __unused)138 static inline struct memory_stat *stats_read_memory_stat(bool per_app_memcg __unused,
139                                     int pid __unused, uid_t uid __unused,
140                                     int64_t rss_bytes __unused, int64_t swap_bytes __unused) {
141     return NULL;
142 }
143 
stats_store_taskname(int pid __unused,const char * taskname __unused)144 static inline void stats_store_taskname(int pid __unused, const char* taskname __unused) {}
145 
stats_purge_tasknames()146 static inline void stats_purge_tasknames() {}
147 
stats_remove_taskname(int pid __unused)148 static inline void stats_remove_taskname(int pid __unused) {}
149 
stats_get_task_name(int pid __unused)150 static inline const char* stats_get_task_name(int pid __unused) { return NULL; }
151 
152 #endif /* LMKD_LOG_STATS */
153 
154 __END_DECLS
155 
156 #endif /* _STATSLOG_H_ */
157