From e71fb4006a9744ef09cabf2ea918c93b2ff7cc3b 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 4e9054676294..1cecd9f640b1 100755 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -595,8 +595,12 @@ static void exit_mm(void) task_unlock(current); mm_update_next_owner(mm); mmput(mm); +#ifdef CONFIG_ANDROID_SIMPLE_LMK + clear_thread_flag(TIF_MEMDIE); +#else if (test_thread_flag(TIF_MEMDIE)) exit_oom_victim(); +#endif } static struct task_struct *find_alive_thread(struct task_struct *p)