From 34899294202298d88a546e2c84f3f701613fc052 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Mon, 24 Feb 2020 19:03:04 -0800 Subject: [PATCH] simple_lmk: Use vmpressure notifier to trigger kills Using kswapd's scan depth to trigger task kills is inconsistent and unreliable. When memory pressure quickly spikes, the kswapd scan depth trigger fails to kick off Simple LMK fast enough, causing severe lag. Additionally, kswapd could stop scanning prematurely before reaching the desired scan depth to trigger Simple LMK, which could also cause stalls. To remedy this, use the vmpressure framework instead, since it provides more consistent and accurate readings on memory pressure. This is not very tunable though, so remove CONFIG_ANDROID_SIMPLE_LMK_AGGRESSION. Triggering Simple LMK to kill when the reported memory pressure is 100 should yield good results on all setups. Signed-off-by: Sultan Alsawaf --- drivers/android/Kconfig | 22 ---------------------- drivers/android/simple_lmk.c | 24 +++++++++++++++++------- include/linux/simple_lmk.h | 4 ---- mm/vmscan.c | 2 -- 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 41a9e244577f..a1793579f159 100755 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -67,28 +67,6 @@ config ANDROID_SIMPLE_LMK if ANDROID_SIMPLE_LMK -config ANDROID_SIMPLE_LMK_AGGRESSION - int "Reclaim frequency selection" - range 1 3 - default 1 - help - This value determines how frequently Simple LMK will perform memory - reclaims. A lower value corresponds to less frequent reclaims, which - maximizes memory usage. The range of values has a logarithmic - correlation; 2 is twice as aggressive as 1, and 3 is twice as - aggressive as 2, which makes 3 four times as aggressive as 1. - - The aggression is set as a factor of kswapd's scan depth. This means - that a system with more memory will have a more expensive aggression - factor compared to a system with less memory. For example, setting an - aggression factor of 1 with 4 GiB of memory would be like setting a - factor of 2 with 8 GiB of memory; the more memory a system has, the - more expensive it is to use a lower value. - - Choosing a value of 1 here works well with systems that have 4 GiB of - memory. If the default doesn't work well, then this value should be - tweaked based on empirical results using different values. - config ANDROID_SIMPLE_LMK_MINFREE int "Minimum MiB of memory to free per reclaim" range 8 512 diff --git a/drivers/android/simple_lmk.c b/drivers/android/simple_lmk.c index 215ee674d82d..2a3316100c79 100644 --- a/drivers/android/simple_lmk.c +++ b/drivers/android/simple_lmk.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* The minimum number of pages to free per reclaim */ @@ -267,13 +268,6 @@ static int simple_lmk_reclaim_thread(void *data) return 0; } -void simple_lmk_decide_reclaim(int kswapd_priority) -{ - if (kswapd_priority == CONFIG_ANDROID_SIMPLE_LMK_AGGRESSION && - !atomic_cmpxchg_acquire(&needs_reclaim, 0, 1)) - wake_up(&oom_waitq); -} - void simple_lmk_mm_freed(struct mm_struct *mm) { int i; @@ -291,6 +285,20 @@ void simple_lmk_mm_freed(struct mm_struct *mm) read_unlock(&mm_free_lock); } +static int simple_lmk_vmpressure_cb(struct notifier_block *nb, + unsigned long pressure, void *data) +{ + if (pressure == 100 && !atomic_cmpxchg_acquire(&needs_reclaim, 0, 1)) + wake_up(&oom_waitq); + + return NOTIFY_OK; +} + +static struct notifier_block vmpressure_notif = { + .notifier_call = simple_lmk_vmpressure_cb, + .priority = INT_MAX +}; + /* Initialize Simple LMK when lmkd in Android writes to the minfree parameter */ static int simple_lmk_init_set(const char *val, const struct kernel_param *kp) { @@ -301,7 +309,9 @@ static int simple_lmk_init_set(const char *val, const struct kernel_param *kp) thread = kthread_run(simple_lmk_reclaim_thread, NULL, "simple_lmkd"); BUG_ON(IS_ERR(thread)); + BUG_ON(vmpressure_notifier_register(&vmpressure_notif)); } + return 0; } diff --git a/include/linux/simple_lmk.h b/include/linux/simple_lmk.h index 28103c1b1d4c..b02d1bec9731 100644 --- a/include/linux/simple_lmk.h +++ b/include/linux/simple_lmk.h @@ -8,12 +8,8 @@ struct mm_struct; #ifdef CONFIG_ANDROID_SIMPLE_LMK -void simple_lmk_decide_reclaim(int kswapd_priority); void simple_lmk_mm_freed(struct mm_struct *mm); #else -static inline void simple_lmk_decide_reclaim(int kswapd_priority) -{ -} static inline void simple_lmk_mm_freed(struct mm_struct *mm) { } diff --git a/mm/vmscan.c b/mm/vmscan.c index f053a584e032..068285f41938 100755 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -3625,7 +3624,6 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx) unsigned long nr_reclaimed = sc.nr_reclaimed; bool raise_priority = true; - simple_lmk_decide_reclaim(sc.priority); sc.reclaim_idx = classzone_idx; /*