From 4d0060a1bc74a12f84764ee384cf87f6a6e2db8e Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Sat, 8 Feb 2020 17:03:35 -0800 Subject: [PATCH] simple_lmk: Mark victim thread group with TIF_MEMDIE The OOM killer sets the TIF_MEMDIE thread flag for its victims to alert other kernel code that the current process was killed due to memory pressure, and needs to finish whatever it's doing quickly. In the page allocator this allows victim processes to quickly allocate memory using emergency reserves. This is especially important when memory pressure is high; if all processes are taking a while to allocate memory, then our victim processes will face the same problem and can potentially get stuck in the page allocator for a while rather than die expeditiously. To ensure that victim processes die quickly, set TIF_MEMDIE for the entire victim thread group. Signed-off-by: Sultan Alsawaf --- drivers/android/simple_lmk.c | 8 +++++++- kernel/exit.c | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/android/simple_lmk.c b/drivers/android/simple_lmk.c index 76f40e99b80d..77172da82701 100644 --- a/drivers/android/simple_lmk.c +++ b/drivers/android/simple_lmk.c @@ -187,7 +187,7 @@ static void scan_and_kill(unsigned long pages_needed) atomic_set_release(&victims_to_kill, nr_to_kill); for (i = 0; i < nr_to_kill; i++) { struct victim_info *victim = &victims[i]; - struct task_struct *vtsk = victim->tsk; + struct task_struct *t, *vtsk = victim->tsk; pr_info("Killing %s with adj %d to free %lu KiB\n", vtsk->comm, vtsk->signal->oom_score_adj, @@ -196,6 +196,12 @@ static void scan_and_kill(unsigned long pages_needed) /* Accelerate the victim's death by forcing the kill signal */ do_send_sig_info(SIGKILL, SEND_SIG_FORCED, vtsk, true); + /* Mark the thread group dead so that other kernel code knows */ + rcu_read_lock(); + for_each_thread(vtsk, t) + set_tsk_thread_flag(t, TIF_MEMDIE); + rcu_read_unlock(); + /* Grab a reference to the victim for later before unlocking */ get_task_struct(vtsk); task_unlock(vtsk); diff --git a/kernel/exit.c b/kernel/exit.c index af35e48dd2fb..2f7b2f0dc43c 100755 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -549,10 +549,14 @@ static void exit_mm(void) mm_update_next_owner(mm); mm_released = mmput(mm); +#ifdef CONFIG_ANDROID_SIMPLE_LMK + clear_thread_flag(TIF_MEMDIE); +#else if (test_thread_flag(TIF_MEMDIE)) exit_oom_victim(); if (mm_released) set_tsk_thread_flag(current, TIF_MM_RELEASED); +#endif } static struct task_struct *find_alive_thread(struct task_struct *p)