lmkd: measure free swap as available and easily reclaimable memory am: 495db5c643 am: c6753329a2

Original change: https://android-review.googlesource.com/c/platform/system/memory/lmkd/+/2233052

Change-Id: Id55391b3d9d6432258eecfc8eeaf21e3214c4d5b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Suren Baghdasaryan 2022-10-10 22:40:55 +00:00 committed by Automerger Merge Worker
commit 775c050f69
1 changed files with 16 additions and 6 deletions

View File

@ -450,6 +450,7 @@ union meminfo {
/* fields below are calculated rather than read from the file */ /* fields below are calculated rather than read from the file */
int64_t nr_file_pages; int64_t nr_file_pages;
int64_t total_gpu_kb; int64_t total_gpu_kb;
int64_t easy_available;
} field; } field;
int64_t arr[MI_FIELD_COUNT]; int64_t arr[MI_FIELD_COUNT];
}; };
@ -1876,10 +1877,19 @@ static int meminfo_parse(union meminfo *mi) {
mi->field.nr_file_pages = mi->field.cached + mi->field.swap_cached + mi->field.nr_file_pages = mi->field.cached + mi->field.swap_cached +
mi->field.buffers; mi->field.buffers;
mi->field.total_gpu_kb = read_gpu_total_kb(); mi->field.total_gpu_kb = read_gpu_total_kb();
mi->field.easy_available = mi->field.nr_free_pages + mi->field.inactive_file;
return 0; return 0;
} }
// In the case of ZRAM, mi->field.free_swap can't be used directly because swap space is taken
// from the free memory or reclaimed. Use the lowest of free_swap and easily available memory to
// measure free swap because they represent how much swap space the system will consider to use
// and how much it can actually use.
static inline int64_t get_free_swap(union meminfo *mi) {
return std::min(mi->field.free_swap, mi->field.easy_available);
}
/* /proc/vmstat parsing routines */ /* /proc/vmstat parsing routines */
static bool vmstat_parse_line(char *line, union vmstat *vs) { static bool vmstat_parse_line(char *line, union vmstat *vs) {
char *cp; char *cp;
@ -2388,7 +2398,7 @@ static int kill_one_process(struct proc* procp, int min_oom_score, struct kill_i
kill_st.oom_score = procp->oomadj; kill_st.oom_score = procp->oomadj;
kill_st.min_oom_score = min_oom_score; kill_st.min_oom_score = min_oom_score;
kill_st.free_mem_kb = mi->field.nr_free_pages * page_k; kill_st.free_mem_kb = mi->field.nr_free_pages * page_k;
kill_st.free_swap_kb = mi->field.free_swap * page_k; kill_st.free_swap_kb = get_free_swap(mi) * page_k;
stats_write_lmk_kill_occurred(&kill_st, mem_st); 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);
@ -2564,7 +2574,7 @@ void calc_zone_watermarks(struct zoneinfo *zi, struct zone_watermarks *watermark
} }
static int calc_swap_utilization(union meminfo *mi) { static int calc_swap_utilization(union meminfo *mi) {
int64_t swap_used = mi->field.total_swap - mi->field.free_swap; int64_t swap_used = mi->field.total_swap - get_free_swap(mi);
int64_t total_swappable = mi->field.active_anon + mi->field.inactive_anon + int64_t total_swappable = mi->field.active_anon + mi->field.inactive_anon +
mi->field.shmem + swap_used; mi->field.shmem + swap_used;
return total_swappable > 0 ? (swap_used * 100) / total_swappable : 0; return total_swappable > 0 ? (swap_used * 100) / total_swappable : 0;
@ -2657,7 +2667,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
/* Check free swap levels */ /* Check free swap levels */
if (swap_free_low_percentage) { if (swap_free_low_percentage) {
swap_low_threshold = mi.field.total_swap * swap_free_low_percentage / 100; swap_low_threshold = mi.field.total_swap * swap_free_low_percentage / 100;
swap_is_low = mi.field.free_swap < swap_low_threshold; swap_is_low = get_free_swap(&mi) < swap_low_threshold;
} else { } else {
swap_low_threshold = 0; swap_low_threshold = 0;
} }
@ -2770,7 +2780,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
kill_reason = LOW_SWAP_AND_THRASHING; kill_reason = LOW_SWAP_AND_THRASHING;
snprintf(kill_desc, sizeof(kill_desc), "device is low on swap (%" PRId64 snprintf(kill_desc, sizeof(kill_desc), "device is low on swap (%" PRId64
"kB < %" PRId64 "kB) and thrashing (%" PRId64 "%%)", "kB < %" PRId64 "kB) and thrashing (%" PRId64 "%%)",
mi.field.free_swap * page_k, swap_low_threshold * page_k, thrashing); get_free_swap(&mi) * page_k, swap_low_threshold * page_k, thrashing);
/* Do not kill perceptible apps unless below min watermark or heavily thrashing */ /* Do not kill perceptible apps unless below min watermark or heavily thrashing */
if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) { if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) {
min_score_adj = PERCEPTIBLE_APP_ADJ + 1; min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
@ -2781,7 +2791,7 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_
kill_reason = LOW_MEM_AND_SWAP; kill_reason = LOW_MEM_AND_SWAP;
snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and swap is low (%" snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and swap is low (%"
PRId64 "kB < %" PRId64 "kB)", wmark < WMARK_LOW ? "min" : "low", PRId64 "kB < %" PRId64 "kB)", wmark < WMARK_LOW ? "min" : "low",
mi.field.free_swap * page_k, swap_low_threshold * page_k); get_free_swap(&mi) * page_k, swap_low_threshold * page_k);
/* Do not kill perceptible apps unless below min watermark or heavily thrashing */ /* Do not kill perceptible apps unless below min watermark or heavily thrashing */
if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) { if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) {
min_score_adj = PERCEPTIBLE_APP_ADJ + 1; min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
@ -3060,7 +3070,7 @@ static void mp_event_common(int data, uint32_t events, struct polling_params *po
// If we still have enough swap space available, check if we want to // If we still have enough swap space available, check if we want to
// ignore/downgrade pressure events. // ignore/downgrade pressure events.
if (mi.field.free_swap >= if (get_free_swap(&mi) >=
mi.field.total_swap * swap_free_low_percentage / 100) { mi.field.total_swap * swap_free_low_percentage / 100) {
// If the pressure is larger than downgrade_pressure lmk will not // If the pressure is larger than downgrade_pressure lmk will not
// kill any process, since enough memory is available. // kill any process, since enough memory is available.