@@ -47,3 +47,4 @@ obj-$(CONFIG_QLGE) += qlge/
obj-$(CONFIG_WIMAX) += wimax/
obj-$(CONFIG_WFX) += wfx/
obj-y += hikey9xx/
+obj-y += oomhelper/
new file mode 100644
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += oomhelper.o
new file mode 100644
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/* prof of concept of android aware oom killer */
+/* Author: peter.enderborg@sony.com */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/oom.h>
+void wake_oom_reaper(struct task_struct *tsk); /* need to public ... */
+void __oom_kill_process(struct task_struct *victim, const char *message);
+
+static int oomhelper_oom_notify(struct notifier_block *self,
+ unsigned long notused, void *param)
+{
+ struct task_struct *tsk;
+ struct task_struct *selected = NULL;
+ int highest = 0;
+
+ pr_info("invited");
+ rcu_read_lock();
+ for_each_process(tsk) {
+ struct task_struct *candidate;
+ if (tsk->flags & PF_KTHREAD)
+ continue;
+
+ /* Ignore task if coredump in progress */
+ if (tsk->mm && tsk->mm->core_state)
+ continue;
+ candidate = find_lock_task_mm(tsk);
+ if (!candidate)
+ continue;
+
+ if (highest < candidate->signal->oom_score_adj) {
+ /* for test dont kill level 0 */
+ highest = candidate->signal->oom_score_adj;
+ selected = candidate;
+ pr_info("new selected %d %d", selected->pid,
+ selected->signal->oom_score_adj);
+ }
+ task_unlock(candidate);
+ }
+ if (selected) {
+ get_task_struct(selected);
+ }
+ rcu_read_unlock();
+ if (selected) {
+ pr_info("oomhelper killing: %d", selected->pid);
+ __oom_kill_process(selected, "oomhelper");
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block oomhelper_oom_nb = {
+ .notifier_call = oomhelper_oom_notify
+};
+
+int __init oomhelper_register_oom_notifier(void)
+{
+ register_oom_notifier(&oomhelper_oom_nb);
+ pr_info("oomhelper installed");
+ return 0;
+}
+
+subsys_initcall(oomhelper_register_oom_notifier);
@@ -658,7 +658,7 @@ static int oom_reaper(void *unused)
return 0;
}
-static void wake_oom_reaper(struct task_struct *tsk)
+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))
@@ -856,7 +856,7 @@ static bool task_will_free_mem(struct task_struct *task)
return ret;
}
-static void __oom_kill_process(struct task_struct *victim, const char *message)
+void __oom_kill_process(struct task_struct *victim, const char *message)
{
struct task_struct *p;
struct mm_struct *mm;