From 141fbd343bf065edfceee69f626d07e9922f8225 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 May 2022 12:02:54 +0200 Subject: [PATCH] Revert "oom_kill.c: futex: delay the OOM reaper to allow time for proper futex cleanup" This reverts commit ed5d4efb4df1014bd5bc1d479e157c7687d8c187 which is commit e4a38402c36e42df28eb1a5394be87e6571fb48a upstream. It breaks the kernel ABI and should not be an issue for Android at this point in time. If it is, it can come back in a different, abi-stable form. Bug: 161946584 Fixes: ed5d4efb4df1 ("oom_kill.c: futex: delay the OOM reaper to allow time for proper futex cleanup") Signed-off-by: Greg Kroah-Hartman Change-Id: I729614c373a7b28546376913e719bbaf6dd306a9 --- include/linux/sched.h | 1 - mm/oom_kill.c | 56 ++++++++++++------------------------------- 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 7d75acf259af..637d25c31374 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1346,7 +1346,6 @@ struct task_struct { int pagefault_disabled; #ifdef CONFIG_MMU struct task_struct *oom_reaper_list; - struct timer_list oom_reaper_timer; #endif #ifdef CONFIG_VMAP_STACK struct vm_struct *stack_vm_area; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index e9cd6e3073ed..e722c6877faf 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -673,7 +673,7 @@ done: */ set_bit(MMF_OOM_SKIP, &mm->flags); - /* Drop a reference taken by queue_oom_reaper */ + /* Drop a reference taken by wake_oom_reaper */ put_task_struct(tsk); } @@ -683,12 +683,12 @@ static int oom_reaper(void *unused) struct task_struct *tsk = NULL; wait_event_freezable(oom_reaper_wait, oom_reaper_list != NULL); - spin_lock_irq(&oom_reaper_lock); + spin_lock(&oom_reaper_lock); if (oom_reaper_list != NULL) { tsk = oom_reaper_list; oom_reaper_list = tsk->oom_reaper_list; } - spin_unlock_irq(&oom_reaper_lock); + spin_unlock(&oom_reaper_lock); if (tsk) oom_reap_task(tsk); @@ -697,46 +697,20 @@ static int oom_reaper(void *unused) return 0; } -static void wake_oom_reaper(struct timer_list *timer) -{ - struct task_struct *tsk = container_of(timer, struct task_struct, - oom_reaper_timer); - struct mm_struct *mm = tsk->signal->oom_mm; - unsigned long flags; - - /* The victim managed to terminate on its own - see exit_mmap */ - if (test_bit(MMF_OOM_SKIP, &mm->flags)) { - put_task_struct(tsk); - return; - } - - spin_lock_irqsave(&oom_reaper_lock, flags); - tsk->oom_reaper_list = oom_reaper_list; - oom_reaper_list = tsk; - spin_unlock_irqrestore(&oom_reaper_lock, flags); - trace_wake_reaper(tsk->pid); - wake_up(&oom_reaper_wait); -} - -/* - * Give the OOM victim time to exit naturally before invoking the oom_reaping. - * The timers timeout is arbitrary... the longer it is, the longer the worst - * case scenario for the OOM can take. If it is too small, the oom_reaper can - * get in the way and release resources needed by the process exit path. - * e.g. The futex robust list can sit in Anon|Private memory that gets reaped - * before the exit path is able to wake the futex waiters. - */ -#define OOM_REAPER_DELAY (2*HZ) -static void queue_oom_reaper(struct task_struct *tsk) +static void wake_oom_reaper(struct task_struct *tsk) { /* mm is already queued? */ if (test_and_set_bit(MMF_OOM_REAP_QUEUED, &tsk->signal->oom_mm->flags)) return; get_task_struct(tsk); - timer_setup(&tsk->oom_reaper_timer, wake_oom_reaper, 0); - tsk->oom_reaper_timer.expires = jiffies + OOM_REAPER_DELAY; - add_timer(&tsk->oom_reaper_timer); + + spin_lock(&oom_reaper_lock); + tsk->oom_reaper_list = oom_reaper_list; + oom_reaper_list = tsk; + spin_unlock(&oom_reaper_lock); + trace_wake_reaper(tsk->pid); + wake_up(&oom_reaper_wait); } static int __init oom_init(void) @@ -746,7 +720,7 @@ static int __init oom_init(void) } subsys_initcall(oom_init) #else -static inline void queue_oom_reaper(struct task_struct *tsk) +static inline void wake_oom_reaper(struct task_struct *tsk) { } #endif /* CONFIG_MMU */ @@ -1006,7 +980,7 @@ static void __oom_kill_process(struct task_struct *victim, const char *message) rcu_read_unlock(); if (can_oom_reap) - queue_oom_reaper(victim); + wake_oom_reaper(victim); mmdrop(mm); put_task_struct(victim); @@ -1042,7 +1016,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) task_lock(victim); if (task_will_free_mem(victim)) { mark_oom_victim(victim); - queue_oom_reaper(victim); + wake_oom_reaper(victim); task_unlock(victim); put_task_struct(victim); return; @@ -1140,7 +1114,7 @@ bool out_of_memory(struct oom_control *oc) */ if (task_will_free_mem(current)) { mark_oom_victim(current); - queue_oom_reaper(current); + wake_oom_reaper(current); return true; }