return 0;
}
oom_adj = mm->oom_adj;
+ if (oom_adj == OOM_DISABLE) {
+ task_unlock(p);
+ return 0;
+ }
/*
* The memory size of the process is the basis for the badness.
*ppoints = ULONG_MAX;
}
- task_lock(p);
- if (p->mm && p->mm->oom_adj == OOM_DISABLE) {
- task_unlock(p);
- continue;
- }
- task_unlock(p);
-
points = badness(p, uptime.tv_sec);
- if (points > *ppoints || !chosen) {
+ if (points > *ppoints) {
chosen = p;
*ppoints = points;
}
return;
}
- if (!p->mm) {
- WARN_ON(1);
- printk(KERN_WARNING "tried to kill an mm-less task!\n");
+ if (!p->mm)
return;
- }
if (verbose)
printk(KERN_ERR "Killed process %d (%s)\n",
struct mm_struct *mm;
struct task_struct *g, *q;
+ task_lock(p);
mm = p->mm;
-
- /* WARNING: mm may not be dereferenced since we did not obtain its
- * value from get_task_mm(p). This is OK since all we need to do is
- * compare mm to q->mm below.
- *
- * Furthermore, even if mm contains a non-NULL value, p->mm may
- * change to NULL at any time since we do not hold task_lock(p).
- * However, this is of no concern to us.
- */
-
- if (mm == NULL)
+ if (!mm || mm->oom_adj == OOM_DISABLE) {
+ task_unlock(p);
return 1;
-
- /*
- * Don't kill the process if any threads are set to OOM_DISABLE
- */
- do_each_thread(g, q) {
- task_lock(q);
- if (q->mm == mm && q->mm && q->mm->oom_adj == OOM_DISABLE) {
- task_unlock(q);
- return 1;
- }
- task_unlock(q);
- } while_each_thread(g, q);
-
+ }
+ task_unlock(p);
__oom_kill_task(p, 1);
/*
/*
* 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 its mm is still attached.
*/
- if (p->flags & PF_EXITING) {
+ if (p->mm && (p->flags & PF_EXITING)) {
__oom_kill_task(p, 0);
return 0;
}