lmkd: report kill reason, and meminfo details to statsd for each kill am: 3cc1f13044
Original change: https://android-review.googlesource.com/c/platform/system/memory/lmkd/+/1424049 Change-Id: Ic70e756c0ac793414c68967a7fe13599da7b0d7d
This commit is contained in:
commit
595d1c19c7
44
lmkd.cpp
44
lmkd.cpp
|
|
@ -800,8 +800,16 @@ static void poll_kernel(int poll_fd) {
|
||||||
ctrl_data_write_lmk_kill_occurred((pid_t)pid, (uid_t)uid);
|
ctrl_data_write_lmk_kill_occurred((pid_t)pid, (uid_t)uid);
|
||||||
mem_st.process_start_time_ns = starttime * (NS_PER_SEC / sysconf(_SC_CLK_TCK));
|
mem_st.process_start_time_ns = starttime * (NS_PER_SEC / sysconf(_SC_CLK_TCK));
|
||||||
mem_st.rss_in_bytes = rss_in_pages * PAGE_SIZE;
|
mem_st.rss_in_bytes = rss_in_pages * PAGE_SIZE;
|
||||||
stats_write_lmk_kill_occurred_pid(uid, pid, oom_score_adj,
|
|
||||||
min_score_adj, &mem_st);
|
struct kill_stat kill_st = {
|
||||||
|
.uid = static_cast<int32_t>(uid),
|
||||||
|
.kill_reason = NONE,
|
||||||
|
.oom_score = oom_score_adj,
|
||||||
|
.min_oom_score = min_score_adj,
|
||||||
|
.free_mem_kb = 0,
|
||||||
|
.free_swap_kb = 0,
|
||||||
|
};
|
||||||
|
stats_write_lmk_kill_occurred_pid(pid, &kill_st, &mem_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(taskname);
|
free(taskname);
|
||||||
|
|
@ -2045,7 +2053,7 @@ static void start_wait_for_proc_kill(int pid_or_fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kill one process specified by procp. Returns the size (in pages) of the process killed */
|
/* Kill one process specified by procp. Returns the size (in pages) of the process killed */
|
||||||
static int kill_one_process(struct proc* procp, int min_oom_score, int kill_reason,
|
static int kill_one_process(struct proc* procp, int min_oom_score, enum kill_reasons kill_reason,
|
||||||
const char *kill_desc, union meminfo *mi, struct wakeup_info *wi,
|
const char *kill_desc, union meminfo *mi, struct wakeup_info *wi,
|
||||||
struct timespec *tm) {
|
struct timespec *tm) {
|
||||||
int pid = procp->pid;
|
int pid = procp->pid;
|
||||||
|
|
@ -2055,6 +2063,7 @@ static int kill_one_process(struct proc* procp, int min_oom_score, int kill_reas
|
||||||
int r;
|
int r;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
struct memory_stat *mem_st;
|
struct memory_stat *mem_st;
|
||||||
|
struct kill_stat kill_st;
|
||||||
int64_t tgid;
|
int64_t tgid;
|
||||||
int64_t rss_kb;
|
int64_t rss_kb;
|
||||||
int64_t swap_kb;
|
int64_t swap_kb;
|
||||||
|
|
@ -2123,7 +2132,14 @@ static int kill_one_process(struct proc* procp, int min_oom_score, int kill_reas
|
||||||
uid, procp->oomadj, rss_kb);
|
uid, procp->oomadj, rss_kb);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats_write_lmk_kill_occurred(uid, taskname, procp->oomadj, min_oom_score, mem_st);
|
kill_st.uid = static_cast<int32_t>(uid);
|
||||||
|
kill_st.taskname = taskname;
|
||||||
|
kill_st.kill_reason = kill_reason;
|
||||||
|
kill_st.oom_score = procp->oomadj;
|
||||||
|
kill_st.min_oom_score = min_oom_score;
|
||||||
|
kill_st.free_mem_kb = mi->field.nr_free_pages * page_k;
|
||||||
|
kill_st.free_swap_kb = mi->field.free_swap * page_k;
|
||||||
|
stats_write_lmk_kill_occurred(&kill_st, mem_st);
|
||||||
|
|
||||||
ctrl_data_write_lmk_kill_occurred((pid_t)pid, uid);
|
ctrl_data_write_lmk_kill_occurred((pid_t)pid, uid);
|
||||||
|
|
||||||
|
|
@ -2142,8 +2158,9 @@ out:
|
||||||
* Find one process to kill at or above the given oom_adj level.
|
* Find one process to kill at or above the given oom_adj level.
|
||||||
* Returns size of the killed process.
|
* Returns size of the killed process.
|
||||||
*/
|
*/
|
||||||
static int find_and_kill_process(int min_score_adj, int kill_reason, const char *kill_desc,
|
static int find_and_kill_process(int min_score_adj, enum kill_reasons kill_reason,
|
||||||
union meminfo *mi, struct wakeup_info *wi, struct timespec *tm) {
|
const char *kill_desc, union meminfo *mi,
|
||||||
|
struct wakeup_info *wi, struct timespec *tm) {
|
||||||
int i;
|
int i;
|
||||||
int killed_size = 0;
|
int killed_size = 0;
|
||||||
bool lmk_state_change_start = false;
|
bool lmk_state_change_start = false;
|
||||||
|
|
@ -2297,17 +2314,6 @@ static int calc_swap_utilization(union meminfo *mi) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_params) {
|
static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_params) {
|
||||||
enum kill_reasons {
|
|
||||||
NONE = -1, /* To denote no kill condition */
|
|
||||||
PRESSURE_AFTER_KILL = 0,
|
|
||||||
NOT_RESPONDING,
|
|
||||||
LOW_SWAP_AND_THRASHING,
|
|
||||||
LOW_MEM_AND_SWAP,
|
|
||||||
LOW_MEM_AND_THRASHING,
|
|
||||||
DIRECT_RECL_AND_THRASHING,
|
|
||||||
LOW_MEM_AND_SWAP_UTIL,
|
|
||||||
KILL_REASON_COUNT
|
|
||||||
};
|
|
||||||
enum reclaim_state {
|
enum reclaim_state {
|
||||||
NO_RECLAIM = 0,
|
NO_RECLAIM = 0,
|
||||||
KSWAPD_RECLAIM,
|
KSWAPD_RECLAIM,
|
||||||
|
|
@ -2756,7 +2762,7 @@ static void mp_event_common(int data, uint32_t events, struct polling_params *po
|
||||||
do_kill:
|
do_kill:
|
||||||
if (low_ram_device) {
|
if (low_ram_device) {
|
||||||
/* For Go devices kill only one task */
|
/* For Go devices kill only one task */
|
||||||
if (find_and_kill_process(level_oomadj[level], -1, NULL, &mi, &wi, &curr_tm) == 0) {
|
if (find_and_kill_process(level_oomadj[level], NONE, NULL, &mi, &wi, &curr_tm) == 0) {
|
||||||
if (debug_process_killing) {
|
if (debug_process_killing) {
|
||||||
ALOGI("Nothing to kill");
|
ALOGI("Nothing to kill");
|
||||||
}
|
}
|
||||||
|
|
@ -2779,7 +2785,7 @@ do_kill:
|
||||||
min_score_adj = level_oomadj[level];
|
min_score_adj = level_oomadj[level];
|
||||||
}
|
}
|
||||||
|
|
||||||
pages_freed = find_and_kill_process(min_score_adj, -1, NULL, &mi, &wi, &curr_tm);
|
pages_freed = find_and_kill_process(min_score_adj, NONE, NULL, &mi, &wi, &curr_tm);
|
||||||
|
|
||||||
if (pages_freed == 0) {
|
if (pages_freed == 0) {
|
||||||
/* Rate limit kill reports when nothing was reclaimed */
|
/* Rate limit kill reports when nothing was reclaimed */
|
||||||
|
|
|
||||||
43
statslog.cpp
43
statslog.cpp
|
|
@ -71,40 +71,61 @@ static struct proc* pid_lookup(int pid) {
|
||||||
return procp;
|
return procp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int32_t map_kill_reason(enum kill_reasons reason) {
|
||||||
|
switch (reason) {
|
||||||
|
case PRESSURE_AFTER_KILL:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__PRESSURE_AFTER_KILL;
|
||||||
|
case NOT_RESPONDING:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__NOT_RESPONDING;
|
||||||
|
case LOW_SWAP_AND_THRASHING:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__LOW_SWAP_AND_THRASHING;
|
||||||
|
case LOW_MEM_AND_SWAP:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP;
|
||||||
|
case LOW_MEM_AND_THRASHING:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_THRASHING;
|
||||||
|
case DIRECT_RECL_AND_THRASHING:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__DIRECT_RECL_AND_THRASHING;
|
||||||
|
case LOW_MEM_AND_SWAP_UTIL:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL;
|
||||||
|
default:
|
||||||
|
return android::lmkd::stats::LMK_KILL_OCCURRED__REASON__UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the event when LMKD kills a process to reduce memory pressure.
|
* Logs the event when LMKD kills a process to reduce memory pressure.
|
||||||
* Code: LMK_KILL_OCCURRED = 51
|
* Code: LMK_KILL_OCCURRED = 51
|
||||||
*/
|
*/
|
||||||
int
|
int stats_write_lmk_kill_occurred(struct kill_stat *kill_st, struct memory_stat *mem_st) {
|
||||||
stats_write_lmk_kill_occurred(int32_t uid, char const* process_name,
|
|
||||||
int32_t oom_score, int32_t min_oom_score,
|
|
||||||
struct memory_stat *mem_st) {
|
|
||||||
if (enable_stats_log) {
|
if (enable_stats_log) {
|
||||||
return android::lmkd::stats::stats_write(
|
return android::lmkd::stats::stats_write(
|
||||||
android::lmkd::stats::LMK_KILL_OCCURRED,
|
android::lmkd::stats::LMK_KILL_OCCURRED,
|
||||||
uid,
|
kill_st->uid,
|
||||||
process_name,
|
kill_st->taskname,
|
||||||
oom_score,
|
kill_st->oom_score,
|
||||||
mem_st ? mem_st->pgfault : -1,
|
mem_st ? mem_st->pgfault : -1,
|
||||||
mem_st ? mem_st->pgmajfault : -1,
|
mem_st ? mem_st->pgmajfault : -1,
|
||||||
mem_st ? mem_st->rss_in_bytes : -1,
|
mem_st ? mem_st->rss_in_bytes : -1,
|
||||||
mem_st ? mem_st->cache_in_bytes : -1,
|
mem_st ? mem_st->cache_in_bytes : -1,
|
||||||
mem_st ? mem_st->swap_in_bytes : -1,
|
mem_st ? mem_st->swap_in_bytes : -1,
|
||||||
mem_st ? mem_st->process_start_time_ns : -1,
|
mem_st ? mem_st->process_start_time_ns : -1,
|
||||||
min_oom_score
|
kill_st->min_oom_score,
|
||||||
|
kill_st->free_mem_kb,
|
||||||
|
kill_st->free_swap_kb,
|
||||||
|
map_kill_reason(kill_st->kill_reason)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int stats_write_lmk_kill_occurred_pid(int32_t uid, int pid, int32_t oom_score,
|
int stats_write_lmk_kill_occurred_pid(int pid, struct kill_stat *kill_st,
|
||||||
int32_t min_oom_score,
|
|
||||||
struct memory_stat* mem_st) {
|
struct memory_stat* mem_st) {
|
||||||
struct proc* proc = pid_lookup(pid);
|
struct proc* proc = pid_lookup(pid);
|
||||||
if (!proc) return -EINVAL;
|
if (!proc) return -EINVAL;
|
||||||
|
|
||||||
return stats_write_lmk_kill_occurred(uid, proc->taskname, oom_score, min_oom_score, mem_st);
|
kill_st->taskname = proc->taskname;
|
||||||
|
return stats_write_lmk_kill_occurred(kill_st, mem_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_stat_parse_line(char* line, struct memory_stat* mem_st) {
|
static void memory_stat_parse_line(char* line, struct memory_stat* mem_st) {
|
||||||
|
|
|
||||||
43
statslog.h
43
statslog.h
|
|
@ -37,6 +37,29 @@ struct memory_stat {
|
||||||
int64_t process_start_time_ns;
|
int64_t process_start_time_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If you update this, also update the corresponding stats enum mapping.
|
||||||
|
enum kill_reasons {
|
||||||
|
NONE = -1, /* To denote no kill condition */
|
||||||
|
PRESSURE_AFTER_KILL = 0,
|
||||||
|
NOT_RESPONDING,
|
||||||
|
LOW_SWAP_AND_THRASHING,
|
||||||
|
LOW_MEM_AND_SWAP,
|
||||||
|
LOW_MEM_AND_THRASHING,
|
||||||
|
DIRECT_RECL_AND_THRASHING,
|
||||||
|
LOW_MEM_AND_SWAP_UTIL,
|
||||||
|
KILL_REASON_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kill_stat {
|
||||||
|
int32_t uid;
|
||||||
|
char *taskname;
|
||||||
|
enum kill_reasons kill_reason;
|
||||||
|
int32_t oom_score;
|
||||||
|
int32_t min_oom_score;
|
||||||
|
int64_t free_mem_kb;
|
||||||
|
int64_t free_swap_kb;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef LMKD_LOG_STATS
|
#ifdef LMKD_LOG_STATS
|
||||||
|
|
||||||
#define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%d/memory.stat"
|
#define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%d/memory.stat"
|
||||||
|
|
@ -56,17 +79,13 @@ stats_write_lmk_state_changed(int32_t state);
|
||||||
* Logs the event when LMKD kills a process to reduce memory pressure.
|
* Logs the event when LMKD kills a process to reduce memory pressure.
|
||||||
* Code: LMK_KILL_OCCURRED = 51
|
* Code: LMK_KILL_OCCURRED = 51
|
||||||
*/
|
*/
|
||||||
int
|
int stats_write_lmk_kill_occurred(struct kill_stat *kill_st, struct memory_stat *mem_st);
|
||||||
stats_write_lmk_kill_occurred(int32_t uid, char const* process_name,
|
|
||||||
int32_t oom_score, int32_t min_oom_score,
|
|
||||||
struct memory_stat *mem_st);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the event when LMKD kills a process to reduce memory pressure.
|
* Logs the event when LMKD kills a process to reduce memory pressure.
|
||||||
* Code: LMK_KILL_OCCURRED = 51
|
* Code: LMK_KILL_OCCURRED = 51
|
||||||
*/
|
*/
|
||||||
int stats_write_lmk_kill_occurred_pid(int32_t uid, int pid, int32_t oom_score,
|
int stats_write_lmk_kill_occurred_pid(int pid, struct kill_stat *kill_st,
|
||||||
int32_t min_oom_score,
|
|
||||||
struct memory_stat* mem_st);
|
struct memory_stat* mem_st);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,14 +115,12 @@ static inline int
|
||||||
stats_write_lmk_state_changed(int32_t state __unused) { return -EINVAL; }
|
stats_write_lmk_state_changed(int32_t state __unused) { return -EINVAL; }
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
stats_write_lmk_kill_occurred(int32_t uid __unused,
|
stats_write_lmk_kill_occurred(struct kill_stat *kill_st __unused,
|
||||||
char const* process_name __unused, int32_t oom_score __unused,
|
struct memory_stat *mem_st __unused) {
|
||||||
int32_t min_oom_score __unused,
|
return -EINVAL;
|
||||||
struct memory_stat *mem_st __unused) { return -EINVAL; }
|
}
|
||||||
|
|
||||||
static inline int stats_write_lmk_kill_occurred_pid(int32_t uid __unused,
|
int stats_write_lmk_kill_occurred_pid(int pid __unused, struct kill_stat *kill_st __unused,
|
||||||
int pid __unused, int32_t oom_score __unused,
|
|
||||||
int32_t min_oom_score __unused,
|
|
||||||
struct memory_stat* mem_st __unused) {
|
struct memory_stat* mem_st __unused) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue