Snap for 4598635 from 93c1ca6224da0bf04df2c424332de87ccf8a1455 to pi-release

Change-Id: I37e06a09af7ccd6ff87a6311731c3261c8f2a30c
This commit is contained in:
android-build-team Robot 2018-02-11 08:20:59 +00:00
commit e30b013acd
3 changed files with 138 additions and 1 deletions

View File

@ -6,6 +6,9 @@ cc_binary {
"liblog", "liblog",
"libcutils", "libcutils",
], ],
static_libs: [
"libstatslogc",
],
local_include_dirs: ["include"], local_include_dirs: ["include"],
cflags: ["-Werror"], cflags: ["-Werror"],
@ -20,7 +23,7 @@ cc_binary {
}, },
} }
cc_library_shared { cc_library_static {
name: "libstatslogc", name: "libstatslogc",
srcs: ["statslog.c"], srcs: ["statslog.c"],
cflags: [ cflags: [

128
lmkd.c
View File

@ -36,6 +36,11 @@
#include <lmkd.h> #include <lmkd.h>
#include <log/log.h> #include <log/log.h>
#ifdef LMKD_LOG_STATS
#include <log/log_event_list.h>
#include <statslog.h>
#endif
/* /*
* Define LMKD_TRACE_KILLS to record lmkd kills in kernel traces * Define LMKD_TRACE_KILLS to record lmkd kills in kernel traces
* to profile and correlate with OOM kills * to profile and correlate with OOM kills
@ -62,6 +67,7 @@
#define MEMCG_SYSFS_PATH "/dev/memcg/" #define MEMCG_SYSFS_PATH "/dev/memcg/"
#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes" #define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes"
#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes" #define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes"
#define LINE_MAX 128 #define LINE_MAX 128
#define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree" #define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree"
@ -70,6 +76,18 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define EIGHT_MEGA (1 << 23) #define EIGHT_MEGA (1 << 23)
#ifdef LMKD_LOG_STATS
#define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%d/pid_%d/memory.stat"
/*
* These are defined in
* http://cs/android/frameworks/base/cmds/statsd/src/atoms.proto
*/
#define LMK_KILL_OCCURRED 51
#define LMK_STATE_CHANGED 54
#define LMK_STATE_CHANGE_START 1
#define LMK_STATE_CHANGE_STOP 2
#endif
/* default to old in-kernel interface if no memory pressure events */ /* default to old in-kernel interface if no memory pressure events */
static int use_inkernel_interface = 1; static int use_inkernel_interface = 1;
static bool has_inkernel_module; static bool has_inkernel_module;
@ -163,6 +181,18 @@ struct proc {
struct proc *pidhash_next; struct proc *pidhash_next;
}; };
#ifdef LMKD_LOG_STATS
struct memory_stat {
int64_t pgfault;
int64_t pgmajfault;
int64_t rss_in_bytes;
int64_t cache_in_bytes;
int64_t swap_in_bytes;
};
static bool enable_stats_log;
static android_log_context log_ctx;
#endif
#define PIDHASH_SZ 1024 #define PIDHASH_SZ 1024
static struct proc *pidhash[PIDHASH_SZ]; static struct proc *pidhash[PIDHASH_SZ];
#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1)) #define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
@ -543,6 +573,51 @@ static void ctrl_connect_handler(int data __unused, uint32_t events __unused) {
maxevents++; maxevents++;
} }
#ifdef LMKD_LOG_STATS
static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
char key[LINE_MAX];
int64_t value;
sscanf(line,"%s %" SCNd64 "", key, &value);
if (strcmp(key, "total_") < 0) {
return;
}
if (!strcmp(key, "total_pgfault"))
mem_st->pgfault = value;
else if (!strcmp(key, "total_pgmajfault"))
mem_st->pgmajfault = value;
else if (!strcmp(key, "total_rss"))
mem_st->rss_in_bytes = value;
else if (!strcmp(key, "total_cache"))
mem_st->cache_in_bytes = value;
else if (!strcmp(key, "total_swap"))
mem_st->swap_in_bytes = value;
}
static int memory_stat_parse(struct memory_stat *mem_st, int pid, uid_t uid) {
FILE *fp;
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
fp = fopen(buf, "r");
if (fp == NULL) {
ALOGE("%s open failed: %s", path, strerror(errno));
return -1;
}
while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
memory_stat_parse_line(buf, mem_st);
}
fclose(fp);
return 0;
}
#endif
static int get_free_memory(struct mem_size *ms) { static int get_free_memory(struct mem_size *ms) {
struct sysinfo si; struct sysinfo si;
@ -639,6 +714,11 @@ static int kill_one_process(struct proc* procp, int min_score_adj,
int tasksize; int tasksize;
int r; int r;
#ifdef LMKD_LOG_STATS
struct memory_stat mem_st;
int memory_stat_parse_result = -1;
#endif
taskname = proc_get_name(pid); taskname = proc_get_name(pid);
if (!taskname) { if (!taskname) {
pid_remove(pid); pid_remove(pid);
@ -651,6 +731,12 @@ static int kill_one_process(struct proc* procp, int min_score_adj,
return -1; return -1;
} }
#ifdef LMKD_LOG_STATS
if (enable_stats_log) {
memory_stat_parse_result = memory_stat_parse(&mem_st, pid, uid);
}
#endif
TRACE_KILL_START(pid); TRACE_KILL_START(pid);
r = kill(pid, SIGKILL); r = kill(pid, SIGKILL);
@ -666,6 +752,15 @@ static int kill_one_process(struct proc* procp, int min_score_adj,
if (r) { if (r) {
ALOGE("kill(%d): errno=%d", pid, errno); ALOGE("kill(%d): errno=%d", pid, errno);
return -1; return -1;
} else {
#ifdef LMKD_LOG_STATS
if (memory_stat_parse_result == 0) {
stats_write_lmk_kill_occurred(log_ctx, LMK_KILL_OCCURRED, uid, taskname,
procp->oomadj, mem_st.pgfault, mem_st.pgmajfault, mem_st.rss_in_bytes,
mem_st.cache_in_bytes, mem_st.swap_in_bytes);
}
#endif
return tasksize;
} }
return tasksize; return tasksize;
@ -683,6 +778,12 @@ static int find_and_kill_processes(enum vmpressure_level level,
int pages_freed = 0; int pages_freed = 0;
int min_score_adj = level_oomadj[level]; int min_score_adj = level_oomadj[level];
#ifdef LMKD_LOG_STATS
if (enable_stats_log) {
stats_write_lmk_state_changed(log_ctx, LMK_STATE_CHANGED, LMK_STATE_CHANGE_START);
}
#endif
for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
struct proc *procp; struct proc *procp;
@ -699,12 +800,25 @@ static int find_and_kill_processes(enum vmpressure_level level,
if (killed_size >= 0) { if (killed_size >= 0) {
pages_freed += killed_size; pages_freed += killed_size;
if (pages_freed >= pages_to_free) { if (pages_freed >= pages_to_free) {
#ifdef LMKD_LOG_STATS
if (enable_stats_log) {
stats_write_lmk_state_changed(log_ctx, LMK_STATE_CHANGED,
LMK_STATE_CHANGE_STOP);
}
#endif
return pages_freed; return pages_freed;
} }
} }
} }
} }
#ifdef LMKD_LOG_STATS
if (enable_stats_log) {
stats_write_lmk_state_changed(log_ctx, LMK_STATE_CHANGED, LMK_STATE_CHANGE_STOP);
}
#endif
return pages_freed; return pages_freed;
} }
@ -1106,6 +1220,14 @@ int main(int argc __unused, char **argv __unused) {
kill_timeout_ms = kill_timeout_ms =
(unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 0); (unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 0);
#ifdef LMKD_LOG_STATS
enable_stats_log = property_get_bool("ro.lmk.log_stats", false);
if (enable_stats_log) {
log_ctx = create_android_logger(kStatsEventTag);
}
#endif
// MCL_ONFAULT pins pages as they fault instead of loading // MCL_ONFAULT pins pages as they fault instead of loading
// everything immediately all at once. (Which would be bad, // everything immediately all at once. (Which would be bad,
// because as of this writing, we have a lot of mapped pages we // because as of this writing, we have a lot of mapped pages we
@ -1122,6 +1244,12 @@ int main(int argc __unused, char **argv __unused) {
if (!init()) if (!init())
mainloop(); mainloop();
#ifdef LMKD_LOG_STATS
if (log_ctx) {
android_log_destroy(&log_ctx);
}
#endif
ALOGI("exiting"); ALOGI("exiting");
return 0; return 0;
} }

View File

@ -19,6 +19,12 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
__BEGIN_DECLS __BEGIN_DECLS
/*
* The single event tag id for all stats logs.
* Keep this in sync with system/core/logcat/event.logtags
*/
const static int kStatsEventTag = 1937006964;
/** /**
* Logs the change in LMKD state which is used as start/stop boundaries for logging * Logs the change in LMKD state which is used as start/stop boundaries for logging
* LMK_KILL_OCCURRED event. * LMK_KILL_OCCURRED event.