oom: consider multi-threaded tasks in task_will_free_mem
[cascardo/linux.git] / include / linux / oom.h
index 03e6257..d3f533f 100644 (file)
@@ -72,12 +72,18 @@ static inline bool oom_task_origin(const struct task_struct *p)
 
 extern void mark_oom_victim(struct task_struct *tsk);
 
+#ifdef CONFIG_MMU
+extern void try_oom_reaper(struct task_struct *tsk);
+#else
+static inline void try_oom_reaper(struct task_struct *tsk)
+{
+}
+#endif
+
 extern unsigned long oom_badness(struct task_struct *p,
                struct mem_cgroup *memcg, const nodemask_t *nodemask,
                unsigned long totalpages);
 
-extern int oom_kills_count(void);
-extern void note_oom_kill(void);
 extern void oom_kill_process(struct oom_control *oc, struct task_struct *p,
                             unsigned int points, unsigned long totalpages,
                             struct mem_cgroup *memcg, const char *message);
@@ -91,7 +97,7 @@ extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
 
 extern bool out_of_memory(struct oom_control *oc);
 
-extern void exit_oom_victim(void);
+extern void exit_oom_victim(struct task_struct *tsk);
 
 extern int register_oom_notifier(struct notifier_block *nb);
 extern int unregister_oom_notifier(struct notifier_block *nb);
@@ -104,13 +110,24 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p);
 
 static inline bool task_will_free_mem(struct task_struct *task)
 {
+       struct signal_struct *sig = task->signal;
+
        /*
         * A coredumping process may sleep for an extended period in exit_mm(),
         * so the oom killer cannot assume that the process will promptly exit
         * and release memory.
         */
-       return (task->flags & PF_EXITING) &&
-               !(task->signal->flags & SIGNAL_GROUP_COREDUMP);
+       if (sig->flags & SIGNAL_GROUP_COREDUMP)
+               return false;
+
+       if (!(task->flags & PF_EXITING))
+               return false;
+
+       /* Make sure that the whole thread group is going down */
+       if (!thread_group_empty(task) && !(sig->flags & SIGNAL_GROUP_EXIT))
+               return false;
+
+       return true;
 }
 
 /* sysctls */