lmkd: check pgrefill vmstat when deciding active reclaim

In rare cases it's possible that pgscan is not changing because inactive
LRU is empty and can't be refilled from the active LRU due to all
pages being hot. In such conditions pgscan_kswapd/pgscan_direct will
not change while pgrefill will be increasing due to active LRU being
scanned. Lmkd would incorrectly treat this situation as if no reclaim
activity happened.
Change lmkd to check pgrefill as well to detect such conditions.

Bug: 288383787
Change-Id: I6b49607429e2f673bba2645ccddff1a141afbcd1
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
Suren Baghdasaryan 2023-07-18 19:38:29 +00:00
parent 1847e9d7ab
commit 4d8791b1f1
1 changed files with 9 additions and 0 deletions

View File

@ -467,6 +467,7 @@ enum vmstat_field {
VS_PGSCAN_KSWAPD, VS_PGSCAN_KSWAPD,
VS_PGSCAN_DIRECT, VS_PGSCAN_DIRECT,
VS_PGSCAN_DIRECT_THROTTLE, VS_PGSCAN_DIRECT_THROTTLE,
VS_PGREFILL,
VS_FIELD_COUNT VS_FIELD_COUNT
}; };
@ -479,6 +480,7 @@ static const char* const vmstat_field_names[VS_FIELD_COUNT] = {
"pgscan_kswapd", "pgscan_kswapd",
"pgscan_direct", "pgscan_direct",
"pgscan_direct_throttle", "pgscan_direct_throttle",
"pgrefill",
}; };
union vmstat { union vmstat {
@ -491,6 +493,7 @@ union vmstat {
int64_t pgscan_kswapd; int64_t pgscan_kswapd;
int64_t pgscan_direct; int64_t pgscan_direct;
int64_t pgscan_direct_throttle; int64_t pgscan_direct_throttle;
int64_t pgrefill;
} field; } field;
int64_t arr[VS_FIELD_COUNT]; int64_t arr[VS_FIELD_COUNT];
}; };
@ -2586,6 +2589,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
static int64_t base_file_lru; static int64_t base_file_lru;
static int64_t init_pgscan_kswapd; static int64_t init_pgscan_kswapd;
static int64_t init_pgscan_direct; static int64_t init_pgscan_direct;
static int64_t init_pgrefill;
static bool killing; static bool killing;
static int thrashing_limit = thrashing_limit_pct; static int thrashing_limit = thrashing_limit_pct;
static struct zone_watermarks watermarks; static struct zone_watermarks watermarks;
@ -2671,9 +2675,14 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
if (vs.field.pgscan_direct != init_pgscan_direct) { if (vs.field.pgscan_direct != init_pgscan_direct) {
init_pgscan_direct = vs.field.pgscan_direct; init_pgscan_direct = vs.field.pgscan_direct;
init_pgscan_kswapd = vs.field.pgscan_kswapd; init_pgscan_kswapd = vs.field.pgscan_kswapd;
init_pgrefill = vs.field.pgrefill;
reclaim = DIRECT_RECLAIM; reclaim = DIRECT_RECLAIM;
} else if (vs.field.pgscan_kswapd != init_pgscan_kswapd) { } else if (vs.field.pgscan_kswapd != init_pgscan_kswapd) {
init_pgscan_kswapd = vs.field.pgscan_kswapd; init_pgscan_kswapd = vs.field.pgscan_kswapd;
init_pgrefill = vs.field.pgrefill;
reclaim = KSWAPD_RECLAIM;
} else if (vs.field.pgrefill != init_pgrefill) {
init_pgrefill = vs.field.pgrefill;
reclaim = KSWAPD_RECLAIM; reclaim = KSWAPD_RECLAIM;
} else if (workingset_refault_file == prev_workingset_refault) { } else if (workingset_refault_file == prev_workingset_refault) {
/* /*