lmkd: Introduce update zoneinfo memevent
This change adds support for the zoneinfo memevent, allowing lmkd to react to memory zone changes and update watermarks dynamically, reducing the need for polling. Polling is retained as a fallback for kernels without support. Bug: 396115949 Test: build and verify on kernel with/without memevent supported Change-Id: I7bc746a0e9dbdc48cfaf80c38c2ead5b5116d20b Merged-In: I7bc746a0e9dbdc48cfaf80c38c2ead5b5116d20b Signed-off-by: Martin Liu <liumartin@google.com>
This commit is contained in:
parent
4636a7dcd5
commit
767ae2336a
43
lmkd.cpp
43
lmkd.cpp
|
|
@ -214,6 +214,7 @@ static struct timespec last_kill_tm;
|
||||||
enum vmpressure_level prev_level = VMPRESS_LEVEL_LOW;
|
enum vmpressure_level prev_level = VMPRESS_LEVEL_LOW;
|
||||||
static bool monitors_initialized;
|
static bool monitors_initialized;
|
||||||
static bool boot_completed_handled = false;
|
static bool boot_completed_handled = false;
|
||||||
|
static bool mem_event_update_zoneinfo_supported;
|
||||||
|
|
||||||
/* lmkd configurable parameters */
|
/* lmkd configurable parameters */
|
||||||
static bool debug_process_killing;
|
static bool debug_process_killing;
|
||||||
|
|
@ -2642,6 +2643,8 @@ struct zone_watermarks {
|
||||||
long min_wmark;
|
long min_wmark;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct zone_watermarks watermarks;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns lowest breached watermark or WMARK_NONE.
|
* Returns lowest breached watermark or WMARK_NONE.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2681,6 +2684,15 @@ void calc_zone_watermarks(struct zoneinfo *zi, struct zone_watermarks *watermark
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int update_zoneinfo_watermarks(struct zoneinfo *zi) {
|
||||||
|
if (zoneinfo_parse(zi) < 0) {
|
||||||
|
ALOGE("Failed to parse zoneinfo!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
calc_zone_watermarks(zi, &watermarks);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int calc_swap_utilization(union meminfo *mi) {
|
static int calc_swap_utilization(union meminfo *mi) {
|
||||||
int64_t swap_used = mi->field.total_swap - get_free_swap(mi);
|
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 +
|
||||||
|
|
@ -2713,7 +2725,6 @@ static void __mp_event_psi(enum event_source source, union psi_event_data data,
|
||||||
static int64_t init_pgrefill;
|
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 timespec wmark_update_tm;
|
static struct timespec wmark_update_tm;
|
||||||
static struct wakeup_info wi;
|
static struct wakeup_info wi;
|
||||||
static struct timespec thrashing_reset_tm;
|
static struct timespec thrashing_reset_tm;
|
||||||
|
|
@ -2896,19 +2907,18 @@ static void __mp_event_psi(enum event_source source, union psi_event_data data,
|
||||||
|
|
||||||
update_watermarks:
|
update_watermarks:
|
||||||
/*
|
/*
|
||||||
* Refresh watermarks once per min in case user updated one of the margins.
|
* Refresh watermarks:
|
||||||
* TODO: b/140521024 replace this periodic update with an API for AMS to notify LMKD
|
* 1. watermarks haven't been initialized (high_wmark == 0)
|
||||||
* that zone watermarks were changed by the system software.
|
* 2. per min in case user updated one of the margins if mem_event update_zoneinfo is NOT
|
||||||
|
* supported.
|
||||||
*/
|
*/
|
||||||
if (watermarks.high_wmark == 0 || get_time_diff_ms(&wmark_update_tm, &curr_tm) > 60000) {
|
if (watermarks.high_wmark == 0 || (!mem_event_update_zoneinfo_supported &&
|
||||||
|
get_time_diff_ms(&wmark_update_tm, &curr_tm) > 60000)) {
|
||||||
struct zoneinfo zi;
|
struct zoneinfo zi;
|
||||||
|
|
||||||
if (zoneinfo_parse(&zi) < 0) {
|
if (update_zoneinfo_watermarks(&zi) < 0) {
|
||||||
ALOGE("Failed to parse zoneinfo!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_zone_watermarks(&zi, &watermarks);
|
|
||||||
wmark_update_tm = curr_tm;
|
wmark_update_tm = curr_tm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3470,11 +3480,17 @@ static void memevent_listener_notification(int data __unused, uint32_t events __
|
||||||
kswapd_start_tm.tv_sec = 0;
|
kswapd_start_tm.tv_sec = 0;
|
||||||
kswapd_start_tm.tv_nsec = 0;
|
kswapd_start_tm.tv_nsec = 0;
|
||||||
break;
|
break;
|
||||||
case MEM_EVENT_VENDOR_LMK_KILL:
|
case MEM_EVENT_VENDOR_LMK_KILL: {
|
||||||
union psi_event_data event_data = {.vendor_event = mem_event};
|
union psi_event_data event_data = {.vendor_event = mem_event};
|
||||||
__mp_event_psi(VENDOR, event_data, 0, poll_params);
|
__mp_event_psi(VENDOR, event_data, 0, poll_params);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MEM_EVENT_UPDATE_ZONEINFO: {
|
||||||
|
struct zoneinfo zi;
|
||||||
|
update_zoneinfo_watermarks(&zi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3512,6 +3528,13 @@ static bool init_memevent_listener_monitoring() {
|
||||||
ALOGI("Failed to register android_vendor_kill memevents");
|
ALOGI("Failed to register android_vendor_kill memevents");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!memevent_listener->registerEvent(MEM_EVENT_UPDATE_ZONEINFO)) {
|
||||||
|
mem_event_update_zoneinfo_supported = false;
|
||||||
|
ALOGI("update_zoneinfo memevents are not supported");
|
||||||
|
} else {
|
||||||
|
mem_event_update_zoneinfo_supported = true;
|
||||||
|
}
|
||||||
|
|
||||||
int memevent_listener_fd = memevent_listener->getRingBufferFd();
|
int memevent_listener_fd = memevent_listener->getRingBufferFd();
|
||||||
if (memevent_listener_fd < 0) {
|
if (memevent_listener_fd < 0) {
|
||||||
memevent_listener.reset();
|
memevent_listener.reset();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue