+ if (mm == NULL)
+ return 1;
+
+ /*
+ * Don't kill the process if any threads are set to OOM_DISABLE
+ */
+ do_each_thread(g, q) {
+ if (q->mm == mm && q->oomkilladj == OOM_DISABLE)
+ return 1;
+ } while_each_thread(g, q);
+
+ __oom_kill_task(p, 1);
+
+ /*
+ * kill all processes that share the ->mm (i.e. all threads),
+ * but are in a different thread group. Don't let them have access
+ * to memory reserves though, otherwise we might deplete all memory.
+ */
+ do_each_thread(g, q) {
+ if (q->mm == mm && q->tgid != p->tgid)
+ force_sig(SIGKILL, q);
+ } while_each_thread(g, q);
+
+ return 0;
+}
+
+static int oom_kill_process(struct task_struct *p, unsigned long points,
+ const char *message)
+{
+ struct task_struct *c;
+ struct list_head *tsk;
+
+ /*
+ * If the task is already exiting, don't alarm the sysadmin or kill
+ * its children or threads, just set TIF_MEMDIE so it can die quickly
+ */
+ if (p->flags & PF_EXITING) {
+ __oom_kill_task(p, 0);
+ return 0;
+ }
+
+ printk(KERN_ERR "%s: kill process %d:#%u (%s) score %li or a child\n",
+ message, p->pid, p->xid, p->comm, points);
+
+ /* Try to kill a child first */
+ list_for_each(tsk, &p->children) {
+ c = list_entry(tsk, struct task_struct, sibling);
+ if (c->mm == p->mm)
+ continue;
+ if (!oom_kill_task(c))
+ return 0;