Index: oom-2.4.21-RHEL3/mm/oom_kill.c =================================================================== --- oom-2.4.21-RHEL3.orig/mm/oom_kill.c 2004-06-23 21:55:28.000000000 +0000 +++ oom-2.4.21-RHEL3/mm/oom_kill.c 2004-06-23 22:10:36.000000000 +0000 @@ -138,7 +138,7 @@ * CAP_SYS_RAW_IO set, send SIGTERM instead (but it's unlikely that * we select a process with CAP_SYS_RAW_IO set). */ -void oom_kill_task(struct task_struct *p) +static void __oom_kill_task(struct task_struct *p) { printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm); @@ -158,6 +158,21 @@ } } +static struct mm_struct *oom_kill_task(struct task_struct *p) +{ + struct mm_struct *mm = get_task_mm(p); + + if (mm) { + if (mm != &init_mm) + __oom_kill_task(p); + else { + mmput(mm); /* don't overflow init_mm.mm_users */ + mm = NULL; + } + } + return mm; +} + /** * oom_kill - kill the "best" process when we run out of memory * @@ -170,10 +185,11 @@ { struct task_struct *g, *p, *q; extern wait_queue_head_t kswapd_done; + struct mm_struct *mm; /* print the memory stats whenever we OOM kill */ show_mem(); - +retry: read_lock(&tasklist_lock); p = select_bad_process(); @@ -181,13 +197,20 @@ if (p == NULL) panic("Out of memory and no killable processes...\n"); + mm = oom_kill_task(p); + if (!mm) { + read_unlock(&tasklist_lock); + goto retry; + } /* kill all processes that share the ->mm (i.e. all threads) */ do_each_thread(g, q) - if (q->mm == p->mm && q->tgid == p->tgid) - oom_kill_task(q); + if (q->mm == mm) + __oom_kill_task(q); while_each_thread(g, q); - + if (!p->mm) + printk(KERN_INFO "Fixed up OOM kill of mm-less task\n"); read_unlock(&tasklist_lock); + mmput(mm); /* Chances are by this time our victim is sleeping on kswapd. */ wake_up(&kswapd_done);