diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index e3c4ccc99..769222257 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -1260,6 +1260,8 @@ static struct proc *proc_get_heaviest(int oomadj) { return maxprocp; } +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 pid = procp->pid; @@ -1304,6 +1306,8 @@ static int kill_one_process(struct proc* procp) { TRACE_KILL_END(); + last_killed_pid = pid; + if (r) { ALOGE("kill(%d): errno=%d", pid, errno); goto out; @@ -1445,6 +1449,23 @@ enum vmpressure_level downgrade_level(enum vmpressure_level level) { level - 1 : level); } +static bool is_kill_pending(void) { + char buf[24]; + + if (last_killed_pid < 0) { + return false; + } + + snprintf(buf, sizeof(buf), "/proc/%d/", last_killed_pid); + if (access(buf, F_OK) == 0) { + return true; + } + + // reset last killed PID because there's nothing pending + last_killed_pid = -1; + return false; +} + static void mp_event_common(int data, uint32_t events __unused) { int ret; unsigned long long evcount; @@ -1490,7 +1511,11 @@ static void mp_event_common(int data, uint32_t events __unused) { } if (kill_timeout_ms) { - if (get_time_diff_ms(&last_kill_tm, &curr_tm) < kill_timeout_ms) { + // If we're within the timeout, see if there's pending reclaim work + // from the last killed process. If there is (as evidenced by + // /proc/ continuing to exist), skip killing for now. + if ((get_time_diff_ms(&last_kill_tm, &curr_tm) < kill_timeout_ms) && + (low_ram_device || is_kill_pending())) { kill_skip_count++; return; } @@ -1633,7 +1658,7 @@ do_kill: min_score_adj = level_oomadj[level]; } - pages_freed = find_and_kill_processes(min_score_adj, pages_to_free); + pages_freed = find_and_kill_processes(min_score_adj, 0); if (pages_freed == 0) { /* Rate limit kill reports when nothing was reclaimed */ @@ -1641,14 +1666,13 @@ do_kill: report_skip_count++; return; } + } else { + /* If we killed anything, update the last killed timestamp. */ + last_kill_tm = curr_tm; } /* Log meminfo whenever we kill or when report rate limit allows */ meminfo_log(&mi); - if (pages_freed >= pages_to_free) { - /* Reset kill time only if reclaimed enough memory */ - last_kill_tm = curr_tm; - } if (use_minfree_levels) { ALOGI("Killing to reclaim %ldkB, reclaimed %ldkB, cache(%ldkB) and "