From 3bcdb496f496474aa278a1fe708247f3264f234d Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Wed, 2 Jun 2021 17:33:03 +0530 Subject: [PATCH] ANDROID: signal: Add vendor hook for memory reaping Add vendor hook to determine if the memory of a process that received the SIGKILL can be reaped. Bug: 189803002 Change-Id: Ie6802b9bf93ddffb0ceef615d7cca40c23219e57 Signed-off-by: Charan Teja Reddy --- drivers/android/vendor_hooks.c | 1 + include/linux/oom.h | 3 +++ include/trace/hooks/signal.h | 3 +++ kernel/signal.c | 11 ++++++++++- mm/oom_kill.c | 36 ++++++++++++++++++++++++++++------ 5 files changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 4489fcd685f2..8b7d0343cb7c 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -83,6 +83,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_restore_priority); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_wakeup_ilocked); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_send_sig_info); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_killed); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_finished); diff --git a/include/linux/oom.h b/include/linux/oom.h index b0c1d73aeb58..61f91f93b7a0 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -129,4 +129,7 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p); extern int sysctl_oom_dump_tasks; extern int sysctl_oom_kill_allocating_task; extern int sysctl_panic_on_oom; + +/* call for adding killed process to reaper. */ +extern void add_to_oom_reaper(struct task_struct *p); #endif /* _INCLUDE_LINUX_OOM_H */ diff --git a/include/trace/hooks/signal.h b/include/trace/hooks/signal.h index ec9c5e86661b..a0db2e8cf77d 100644 --- a/include/trace/hooks/signal.h +++ b/include/trace/hooks/signal.h @@ -12,6 +12,9 @@ struct task_struct; DECLARE_HOOK(android_vh_do_send_sig_info, TP_PROTO(int sig, struct task_struct *killer, struct task_struct *dst), TP_ARGS(sig, killer, dst)); +DECLARE_HOOK(android_vh_process_killed, + TP_PROTO(struct task_struct *task, bool *reap), + TP_ARGS(task, reap)); #endif /* _TRACE_HOOK_SIGNAL_H */ /* This part must be outside protection */ #include diff --git a/kernel/signal.c b/kernel/signal.c index 2a1e8476cca0..cae67cc698d7 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -46,6 +46,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -1413,8 +1414,16 @@ int group_send_sig_info(int sig, struct kernel_siginfo *info, ret = check_kill_permission(sig, info, p); rcu_read_unlock(); - if (!ret && sig) + if (!ret && sig) { ret = do_send_sig_info(sig, info, p, type); + if (!ret && sig == SIGKILL) { + bool reap = false; + + trace_android_vh_process_killed(current, &reap); + if (reap) + add_to_oom_reaper(p); + } + } return ret; } diff --git a/mm/oom_kill.c b/mm/oom_kill.c index e376f72d0d9a..acf064f3fc4e 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -724,6 +724,20 @@ static inline void wake_oom_reaper(struct task_struct *tsk) } #endif /* CONFIG_MMU */ +/** + * tsk->mm has to be non NULL and caller has to guarantee it is stable (either + * under task_lock or operate on the current). + */ +static void __mark_oom_victim(struct task_struct *tsk) +{ + struct mm_struct *mm = tsk->mm; + + if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) { + mmgrab(tsk->signal->oom_mm); + set_bit(MMF_OOM_VICTIM, &mm->flags); + } +} + /** * mark_oom_victim - mark the given task as OOM victim * @tsk: task to mark @@ -736,18 +750,13 @@ static inline void wake_oom_reaper(struct task_struct *tsk) */ static void mark_oom_victim(struct task_struct *tsk) { - struct mm_struct *mm = tsk->mm; - WARN_ON(oom_killer_disabled); /* OOM killer might race with memcg OOM */ if (test_and_set_tsk_thread_flag(tsk, TIF_MEMDIE)) return; /* oom_mm is bound to the signal struct life time. */ - if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) { - mmgrab(tsk->signal->oom_mm); - set_bit(MMF_OOM_VICTIM, &mm->flags); - } + __mark_oom_victim(tsk); /* * Make sure that the task is woken up from uninterruptible sleep @@ -1185,3 +1194,18 @@ void pagefault_out_of_memory(void) out_of_memory(&oc); mutex_unlock(&oom_lock); } + +void add_to_oom_reaper(struct task_struct *p) +{ + p = find_lock_task_mm(p); + if (!p) + return; + + get_task_struct(p); + if (task_will_free_mem(p)) { + __mark_oom_victim(p); + wake_oom_reaper(p); + } + task_unlock(p); + put_task_struct(p); +}