lmkd: Prevent killing foreground processes due to thrashing

Page cache thrashing affects device performance and by killing a process
we try to stop it. However if the thrashing application is the one which
user is interacting with then lmkd should not kill it even though it might
affect device performance.

Bug: 141286980
Test: SequentialRWTest CTS test
Change-Id: If86c0e7e8ad9adf1816659562151ca083eaa65c4
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
Suren Baghdasaryan 2019-09-19 15:27:21 -07:00
parent 89454e620c
commit 970a26aeb7
1 changed files with 21 additions and 4 deletions

25
lmkd.c
View File

@ -83,6 +83,8 @@
#define PROC_STATUS_TGID_FIELD "Tgid:" #define PROC_STATUS_TGID_FIELD "Tgid:"
#define LINE_MAX 128 #define LINE_MAX 128
#define PERCEPTIBLE_APP_ADJ 200
/* Android Logger event logtags (see event.logtags) */ /* Android Logger event logtags (see event.logtags) */
#define MEMINFO_LOG_TAG 10195355 #define MEMINFO_LOG_TAG 10195355
@ -2046,6 +2048,8 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
enum reclaim_state reclaim = NO_RECLAIM; enum reclaim_state reclaim = NO_RECLAIM;
enum zone_watermark wmark = WMARK_NONE; enum zone_watermark wmark = WMARK_NONE;
char kill_desc[LINE_MAX]; char kill_desc[LINE_MAX];
bool cut_thrashing_limit = false;
int min_score_adj = 0;
/* Skip while still killing a process */ /* Skip while still killing a process */
if (is_kill_pending()) { if (is_kill_pending()) {
@ -2164,22 +2168,35 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
mi.field.free_swap * page_k, swap_low_threshold * page_k); mi.field.free_swap * page_k, swap_low_threshold * page_k);
} else if (wmark < WMARK_HIGH && thrashing > thrashing_limit) { } else if (wmark < WMARK_HIGH && thrashing > thrashing_limit) {
/* Page cache is thrashing while memory is low */ /* Page cache is thrashing while memory is low */
thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100;
kill_reason = LOW_MEM_AND_THRASHING; kill_reason = LOW_MEM_AND_THRASHING;
snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and thrashing (%" snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and thrashing (%"
PRId64 "%%)", wmark > WMARK_LOW ? "min" : "low", thrashing); PRId64 "%%)", wmark > WMARK_LOW ? "min" : "low", thrashing);
cut_thrashing_limit = true;
/* Do not kill perceptible apps because of thrashing */
min_score_adj = PERCEPTIBLE_APP_ADJ;
} else if (reclaim == DIRECT_RECLAIM && thrashing > thrashing_limit) { } else if (reclaim == DIRECT_RECLAIM && thrashing > thrashing_limit) {
/* Page cache is thrashing while in direct reclaim (mostly happens on lowram devices) */ /* 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; kill_reason = DIRECT_RECL_AND_THRASHING;
snprintf(kill_desc, sizeof(kill_desc), "device is in direct reclaim and thrashing (%" snprintf(kill_desc, sizeof(kill_desc), "device is in direct reclaim and thrashing (%"
PRId64 "%%)", thrashing); PRId64 "%%)", thrashing);
cut_thrashing_limit = true;
/* Do not kill perceptible apps because of thrashing */
min_score_adj = PERCEPTIBLE_APP_ADJ;
} }
/* Kill a process if necessary */ /* Kill a process if necessary */
if (kill_reason != NONE) { if (kill_reason != NONE) {
int pages_freed = find_and_kill_process(0, kill_desc); int pages_freed = find_and_kill_process(min_score_adj, kill_desc);
killing = (pages_freed > 0); if (pages_freed > 0) {
killing = true;
if (cut_thrashing_limit) {
/*
* Cut thrasing limit by thrashing_limit_decay_pct percentage of the current
* thrashing limit until the system stops thrashing.
*/
thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100;
}
}
meminfo_log(&mi); meminfo_log(&mi);
} }