lmkd: Add optional kill reason description into kill reports
am: fd7518f8c1 Change-Id: Id638e3307138f92a85d985fb1177bc67109f2cc5
This commit is contained in:
commit
da4267b006
34
lmkd.c
34
lmkd.c
|
|
@ -1743,7 +1743,7 @@ static void set_process_group_and_prio(int pid, SchedPolicy sp, int prio) {
|
|||
static int last_killed_pid = -1;
|
||||
|
||||
/* Kill one process specified by procp. Returns the size of the process killed */
|
||||
static int kill_one_process(struct proc* procp, int min_oom_score) {
|
||||
static int kill_one_process(struct proc* procp, int min_oom_score, const char *reason) {
|
||||
int pid = procp->pid;
|
||||
uid_t uid = procp->uid;
|
||||
int tgid;
|
||||
|
|
@ -1794,8 +1794,13 @@ static int kill_one_process(struct proc* procp, int min_oom_score) {
|
|||
set_process_group_and_prio(pid, SP_FOREGROUND, ANDROID_PRIORITY_HIGHEST);
|
||||
|
||||
inc_killcnt(procp->oomadj);
|
||||
ALOGE("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid, uid, procp->oomadj,
|
||||
tasksize * page_k);
|
||||
if (reason) {
|
||||
ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB; reason: %s", taskname, pid,
|
||||
uid, procp->oomadj, tasksize * page_k, reason);
|
||||
} else {
|
||||
ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid,
|
||||
uid, procp->oomadj, tasksize * page_k);
|
||||
}
|
||||
|
||||
TRACE_KILL_END();
|
||||
|
||||
|
|
@ -1833,7 +1838,7 @@ out:
|
|||
* Find one process to kill at or above the given oom_adj level.
|
||||
* Returns size of the killed process.
|
||||
*/
|
||||
static int find_and_kill_process(int min_score_adj) {
|
||||
static int find_and_kill_process(int min_score_adj, const char *reason) {
|
||||
int i;
|
||||
int killed_size = 0;
|
||||
|
||||
|
|
@ -1851,7 +1856,7 @@ static int find_and_kill_process(int min_score_adj) {
|
|||
if (!procp)
|
||||
break;
|
||||
|
||||
killed_size = kill_one_process(procp, min_score_adj);
|
||||
killed_size = kill_one_process(procp, min_score_adj, reason);
|
||||
if (killed_size >= 0) {
|
||||
#ifdef LMKD_LOG_STATS
|
||||
if (enable_stats_log && !lmk_state_change_start) {
|
||||
|
|
@ -2040,6 +2045,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
|
|||
bool cycle_after_kill = false;
|
||||
enum reclaim_state reclaim = NO_RECLAIM;
|
||||
enum zone_watermark wmark = WMARK_NONE;
|
||||
char kill_desc[LINE_MAX];
|
||||
|
||||
/* Skip while still killing a process */
|
||||
if (is_kill_pending()) {
|
||||
|
|
@ -2135,6 +2141,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
|
|||
* free even after a kill. Mostly happens when running memory stress tests.
|
||||
*/
|
||||
kill_reason = PRESSURE_AFTER_KILL;
|
||||
strncpy(kill_desc, "min watermark is breached even after kill", sizeof(kill_desc));
|
||||
} else if (level == VMPRESS_LEVEL_CRITICAL && events != 0) {
|
||||
/*
|
||||
* Device is too busy reclaiming memory which might lead to ANR.
|
||||
|
|
@ -2142,25 +2149,36 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
|
|||
* of the memory congestion) breaches the configured threshold.
|
||||
*/
|
||||
kill_reason = NOT_RESPONDING;
|
||||
strncpy(kill_desc, "device is not responding", sizeof(kill_desc));
|
||||
} else if (swap_is_low && thrashing > thrashing_limit_pct) {
|
||||
/* Page cache is thrashing while swap is low */
|
||||
kill_reason = LOW_SWAP_AND_THRASHING;
|
||||
snprintf(kill_desc, sizeof(kill_desc), "device is low on swap (%" PRId64
|
||||
"kB < %" PRId64 "kB) and thrashing (%" PRId64 "%%)",
|
||||
mi.field.free_swap * page_k, swap_low_threshold * page_k, thrashing);
|
||||
} else if (swap_is_low && wmark < WMARK_HIGH) {
|
||||
/* Both free memory and swap are low */
|
||||
kill_reason = LOW_MEM_AND_SWAP;
|
||||
snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and swap is low (%"
|
||||
PRId64 "kB < %" PRId64 "kB)", wmark > WMARK_LOW ? "min" : "low",
|
||||
mi.field.free_swap * page_k, swap_low_threshold * page_k);
|
||||
} else if (wmark < WMARK_HIGH && thrashing > thrashing_limit) {
|
||||
/* Page cache is thrashing while memory is low */
|
||||
thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100;
|
||||
kill_reason = LOW_MEM_AND_THRASHING;
|
||||
snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and thrashing (%"
|
||||
PRId64 "%%)", wmark > WMARK_LOW ? "min" : "low", thrashing);
|
||||
} else if (reclaim == DIRECT_RECLAIM && thrashing > thrashing_limit) {
|
||||
/* Page cache is thrashing while in direct reclaim (mostly happens on lowram devices) */
|
||||
thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100;
|
||||
kill_reason = DIRECT_RECL_AND_THRASHING;
|
||||
snprintf(kill_desc, sizeof(kill_desc), "device is in direct reclaim and thrashing (%"
|
||||
PRId64 "%%)", thrashing);
|
||||
}
|
||||
|
||||
/* Kill a process if necessary */
|
||||
if (kill_reason != NONE) {
|
||||
int pages_freed = find_and_kill_process(0);
|
||||
int pages_freed = find_and_kill_process(0, kill_desc);
|
||||
killing = (pages_freed > 0);
|
||||
meminfo_log(&mi);
|
||||
}
|
||||
|
|
@ -2351,7 +2369,7 @@ static void mp_event_common(int data, uint32_t events, struct polling_params *po
|
|||
do_kill:
|
||||
if (low_ram_device) {
|
||||
/* For Go devices kill only one task */
|
||||
if (find_and_kill_process(level_oomadj[level]) == 0) {
|
||||
if (find_and_kill_process(level_oomadj[level], NULL) == 0) {
|
||||
if (debug_process_killing) {
|
||||
ALOGI("Nothing to kill");
|
||||
}
|
||||
|
|
@ -2376,7 +2394,7 @@ do_kill:
|
|||
min_score_adj = level_oomadj[level];
|
||||
}
|
||||
|
||||
pages_freed = find_and_kill_process(min_score_adj);
|
||||
pages_freed = find_and_kill_process(min_score_adj, NULL);
|
||||
|
||||
if (pages_freed == 0) {
|
||||
/* Rate limit kill reports when nothing was reclaimed */
|
||||
|
|
|
|||
Loading…
Reference in New Issue