Snap for 4598635 from 93c1ca6224da0bf04df2c424332de87ccf8a1455 to pi-release
Change-Id: I37e06a09af7ccd6ff87a6311731c3261c8f2a30c
This commit is contained in:
commit
e30b013acd
|
|
@ -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
128
lmkd.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue